javascript - Get pixel data back from programmatically generated image -
i generate array of pixels in client side javascript code , convert blob. pass url of blob image.src , revoke @ image.onload callback. don't keep references data, generated previous steps, data may freed gc.
there many images generated way, , works fine. user may want save generated image clicking on save button near image. don't want generate image again, because generation slow, , image generated , visible on screen. want pixels image. tried create canvas again, draw image on , call toblob, browser treats image cross origin , throws exception: "failed execute 'toblob' on 'htmlcanvaselement': tainted canvases may not exported". similar errors canvas.todataurl , canvascontext.getimagedata.
is there workaround problem?
i tried create canvases instead of images, when create second canvas, content of first 1 clears.
added error occurs in chrome , other webkit browsers. firefox , ms edge work fine. , when commented out line of code revoked blob url, error disappeared - can draw image on canvas , pixel data without cors issues. pointless so, because have blob not deleted. page may generate many images - depends on user , unlimited. size of images unlimited - may useful generate 4096x4096 images. want reduce memory consumption of page as possible. , these images should downloadable. generation of images uses generated images, regenerate last image in chain, must regenerate images.
so need workaround chrome browser.
added 2 tried reproduce problem in js fiddle, couldn't. locally code doesn't work - developed app locally , haven't tried running on server. create test.html file on computer , open in browser (locally, without server):
<html> <body> <pre id="log"></pre> </body> <script> var log = document.getelementbyid("log"); var canvas = document.createelement("canvas"); canvas.width = canvas.height = 256; var ctx = canvas.getcontext("2d"); canvas.toblob(function(blob) { var img = new image(); var bloburl = url.createobjecturl(blob); img.src = bloburl; img.onload = function() { url.revokeobjecturl(bloburl); ctx.drawimage(img, 0, 0); try { canvas.toblob(function(blob) { log.textcontent += 'success\n'; }); } catch(e) {log.textcontent += e.message + '\n';} }; }); </script> </html>
it print failed execute 'toblob' on 'htmlcanvaselement': tainted canvases may not exported.
. so, think, workaround detect page run on combination of webkit browser , file:///
protocol. , can defer revoking blob url until page unload combination.
that indeed sounds bug in chrome's implementation, you may want report it.
what seems happen chrome checks if image has been loaded through clean origin when drawn first time on canvas.
since @ time, did revoke bloburi, can't map uri clean origin (file://
protocol quite strict on chrome).
but there seems simple workaround:
by drawing image on a [the reviver]* canvas before revoking bloburi, chrome mark image clean, , remember it.
*[edit] seems needs same canvas...
so can create export canvas before-hand, , draw each images on (to save memory can set 1x1px when don't use export) before revoke image's src:
// somewhere accessible export logic var reviver = document.createelement('canvas').getcontext('2d'); // in canvas img logic canvas.toblob(function(blob){ var img = new image(); img.onload = function(){ reviver.canvas.width = reviver.canvas.height = 1; // save memory reviver.drawimage(this, 0,0); // mark our image origin clean url.revokeobjecturl(this.src); } img.src = url.createobjecturl(blob); probablysaveinanarray(img); }; // , when want save images disk function reviveblob(img){ reviver.canvas.width = img.width; reviver.canvas.height = img.height; reviver.drawimage(img,0,0); reviver.canvas.toblob(... }
but note method create new blob, not retrieve previous one, has been collected garbagecollector @ time. unfortunately way since did revoke bloburi...
Comments
Post a Comment