Canvas convert to Bitmap BLOB.
Javascriptã§å€§éã®ãµã ãã€ã«ç»åãçæããå¿ èŠããã£ãã®ã§ãã®ã話ã§ãã
Javascriptã§ç»åã®ãµã ãã€ã«ãäœæããå Žåã®å®çªçãªææ³ãšããŠã
Imageãäœæ
Canvasã«Imageãæžã蟌ã¿
Canvasã§å€åœ¢
CanvasããData URLã«å€æ
ãšããæµãããããŸãã
var img = new Image(); img.src = '/path/to/filename'; img.onload = function() { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var w = maxWidth/this.naturalWidth; var h = maxHeight/this.naturalHeight; var rate = w <= h ? w : h; rate = rate < 1 ? rate : 1; canvas.width = Math.round(this.naturalWidth*rate); canvas.height = Math.round(this.naturalHeight*rate); ctx.drawImage(this, 0, 0, this.naturalWidth, this.naturalHeight, 0, 0, canvas.width, canvas.height); if (this.src.match(/^data:image\/jpeg;/)) { this.src = canvas.toDataURL('image/jpeg', 1.0); } else { this.src = canvas.toDataURL(); } };
ãã ãããã®æ¹æ³ã¯åãéãã§ãã äžã€ã®ç»åã®ãµã ãã€ã«ãäœãã ããªãæ°ã«ãªãã»ã©ã®éãã§ã¯ãªãã®ã§ãããäœæããµã ãã€ã«ãäœããšã¡ã€ã³ã¹ã¬ãããå®å šã«åºãŸã£ãŠããŸãã»ã©ã®éãã«ãªããŸãã äœãéãããšãããšcanvas.toDataURLããã®åŠçã®å€§éšåããããåå ã«ãªããŸãã ïŒdrawImageã§å€åœ¢ãããšéãã®ã§setTransform䜿ãå¿ èŠããããã©ããã®è©±ã¯å²æïŒ
ä»ã®æ¹æ³ãšããŠW3Cã®æ¹ãã¿ããšcanvas.toBlobãšããã¡ãœããã§éåæã«çæã§ããŸãããå®è£ ãããŠãããã©ãŠã¶ããªãã®ã§èªåã§å¥ã®æ¹æ³ãå®è£ ããå¿ èŠããããŸãã ãã®ãããåãé¢åèãã®ã§ããCanvasã®ç»åããŒã¿ããèªåã§ç»åã®ãã€ããªãäœæããŸãã ã
Get image data from Canvas
ãŸãã¯Canvasããç»åã®ãã¯ã»ã«ããŒã¿ãååŸããŸãã
var ctx = canvas.getContext('2d'); var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
ååŸããimageDataã®imageData.dataããRGBAã§4èŠçŽ ãåã1次å é åãååŸããããšãã§ããŸãã
var red = imageData.data[0]; var green = imageData.data[1]; var blue = imageData.data[2]; var alpha = imageData.data[3];
Create Bitmap header
ç»åã®ãã¯ã»ã«ããŒã¿ã®æºåãåºæ¥ãããæ¬¡ã«Bitmapç»åãäœæããŠãããŸãã ãŸãã¯Bitmapã®ããããŒãçæããŸãã
function getLittleEndianHex(value) { var result = []; for (var bytes = 4; bytes > 0; bytes--) { result.push(String.fromCharCode(value & 255)); value >>= 8; } return result.join(''); } var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); var bodyByteSize = imageData.data.length; // create header string var header = 'BM' + getLittleEndianHex(bodyByteSize) '\x00\x00' + '\x00\x00' + '\x36\x00\x00\x00' + '\x28\x00\x00\x00' + getLittleEndianHex(canvas.width) + getLittleEndianHex(canvas.height) + '\x01\x00' + '\x20\x00' + '\x00\x00\x00\x00' + '\x00\x00\x00\x00' + '\x13\x0B\x00\x00' + '\x13\x0B\x00\x00' + '\x00\x00\x00\x00' + '\x00\x00\x00\x00';
â» åèãµã€ã http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/
Write Bitmap data to ArrayBuffer
ããã§æºåãåºæ¥ãã®ã§ãArrayBufferã«Bitmapã®ããããšç»åã®ãã¯ã»ã«ããŒã¿ãæžã蟌ãã§ãããŸãã
// create buffer var buf = new ArrayBuffer(byteSize + header.length + 4 - (header.length % 4); var data8 = new Uint8Array(buf); var data32 = new Uint32Array(buf); // write header for (var i = 0; i < header.length; i++) { data8[i] = header.charCodeAt(i); } // write image data for (var x = 0, z = Math.ceil(header.length % 4); x < width; x++) { for (var y = 0; y < height; y++) { var i = (width * y) + x; var j = (width * (height - y)) - (width - x) + z; data32[j] = (imageData.data[(i*4)+1] << 24) | (imageData.data[(i*4)+2] << 16) | (imageData.data[(i*4)+3] << 8) | (imageData.data[(i*4)+0]) || -1; } }
泚æç¹ãšããŠUint32Arrayãçæãããšãã¯4ãã€ãåäœã®é·ãã«ããããšã BitmapãšCanvasã®ãã¯ã»ã«ããŒã¿ã§ããŒã¿ã§ã¯y座æšãéã«ãªããšããç¹ã«æ°ãã€ããŠãã ããã
Convert ArrayBuffer to Blob and Blob URL
æåŸã«äœæããArrayBufferãBlobã«å€æããããããBlob URLã«å€æããŸãã
var b = new Blob([buf, {type: 'image/bmp'}); var url = URL.createObjectURL(b); var img = new Image(); img.src = url; img.onload = function() { URLrevokeObjectURL(img.src); }
URL.createObjectURLã§äœæã§ããBlob URLã®æ°ã¯æ±ºãŸã£ãŠãããããBlob URLãäœæãããå¿ ãããã«URLrevokeObjectURLã§è§£æŸããŠãããå¿ èŠããããŸãã ãã¡ããšèšæž¬ããèš³ã§ã¯ãããŸããã200ã400ãããã§Blob URLã®ç¢ºä¿ã«å€±æããŠèªã¿èŸŒããªãURLãåºæ¥å§ããŸãã ïŒURL.createObjectURLèªäœã¯æåããã®ã§ãèªã¿èŸŒããŸã§å€±æãããã©ããããããŸããïŒ
Exceute on worker
ããã§CanvasããBlob URLãžã®å€æãã§ããŸããããcanvas.toDataURLãããããã©ãŒãã³ã¹ãæªåããŠããŸãã ããã§ãWorkerã䜿ã£ãŠå¥ã¹ã¬ããã§åŠçãè¡ããŸãã ã¡ããã©imageDataãTransferableãªãªããžã§ã¯ãã®ãããWorkerã«å€§ããªããŒã¿ãæž¡ããŠããããŸã§é å»¶ããã«ããŒã¿ã®ããåããè¡ããŸãã
// worker function function canvasToBlob() { self.addEventListener('message', function(event) { // create bitmap ... self.postMessage({buffer: buf}, [buf]); }); } // generate worker var workerFnString = '(' + canvasToBlob.toString() + ')()'; var workerblob = new Blob([workerFnString], {type: 'text/javascript'}); var workerUrl = URL.createObjectURL(workerblob); var worker = new Worker(workerUrl); // revoke url URL.revokeObjectURL(workerUrl); worker.addEventListener('message', function(e) { var b = new Blob([e.data.buffer], {type: 'image/bmp'}); var url = URL.createObjectURL(b); // apply object var img = new Image(); img.src = url; img.onload = function() { URL.revokeObjectURL(img.src); }); }); worker.postMessage({imageData: imageData}, [imageData.data.buffer]);
ããã§ã¡ã€ã³ã¹ã¬ããããããã¯ããã«å®è¡ã§ããããã«ãªããŸããã
â»åèãµã€ã http://lab.sonicmoov.com/development/web-workers-with-transferable-objects/
ä»ã«ããªãµã€ãºåŠçãWorkerã§ãã£ãããåæå®è¡æ°ãå¶éããããšã§ã¡ã€ã³ã¹ã¬ãããåºããã®ãé²ãããšãã§ããŸãã å°æ¥çã«ã¯Workeräžã§Canvasãæäœã§ããCanvasProxyããCanvasããBlobãçæã§ããtoBlobããããããå°ãããã©ãŒãã³ã¹ãè¯ãã§ãããšæããŸãã
ãããããŸããJSã§Bitmapã®ä»æ§ã調ã¹ãããšã«ãªããšã¯æããŸããã§ããããã åºæ¬çã«ãã©ãŠã¶ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãµãŒããŒãµã€ãã§ãµã ãã€ã«ãçæããã®ããã¹ããªéžæãªã®ã§ãã©ãããŠãã¯ã©ã€ã¢ã³ããµã€ãã§çæããªããšãããªãçç±ããªããšãã¯ãµãŒããŒãµã€ãã§çæããããã«ããŠãã ããã













