2012-02-28 383 views
0

我使用畫布標記在這DISPLY一些矩形我已經使用這個代碼如何將RGBA數據轉換爲base64顯示圖像

var canvas=document.getElementById("myCanvas"); 

    if (canvas.getContext) { 
     var ctx=canvas.getContext("2d"); 
     ctx.fillStyle="red"; 
     ctx.fillRect(0,0,50,50); 

     var newRGBA=new Array(); 

    // and can't do the ctx.ToDataUrl("image/png") bc in andriod 2.2 this not supported 
     // here canvas returns me the Array RGBA 
    newRGBA= ctx.getImageData(0,0,50,50); 
} 

我的查詢是如何將這些數據綁定到image.src = RGBAdata; 我已經試過這

document.getElementById("imgid").src="data:image/png;base64," + btoa(String.fromCharCode.apply(this,newRGBA.data))+" "; 
+0

這與Android有什麼關係? – Ruuhkis 2012-02-28 07:14:44

+1

這並不像你想象的那麼簡單,你現在擁有的只是一個圖像像素數組,但它本身並不是任何有效的圖像格式,比如PNG或BMP,這是瀏覽器在img標籤上所期望的。 是的,可以做你想做的事情,但它需要你花時間學習圖像格式的文件規範,最簡單的可能是BMP。然後使用二進制字符串來建立圖像文件,然後將其轉換爲base64。 – Delta 2012-02-28 07:23:10

+0

@Ruuhkis謝謝你的回覆,但是當我使用ToDataUrl(「image/png」)時,它會返回數據:,在模擬器2.2v中,在瀏覽器中它工作正常,它提供了所有base64數據和如果我使用4.0v,那麼它將返回模擬器中的所有base64數據。 – Tamkeen 2012-02-28 07:36:37

回答

1

toDataURL是沒有在android 2.x中實現,所以我做了一些解決方法涉及從畫布創建一個BMP base64數據和png base64。

參考 1使從畫布pngbase64。 2從畫布製作BMP base64

//code here for pngbase64 from canvas: 

Number.prototype.toUInt = function() { return this < 0 ? this + 4294967296 : this; }; 
Number.prototype.bytes32 = function() { return [(this >>> 24) & 0xff, (this >>> 16) & 0xff, (this >>> 8) & 0xff, this & 0xff]; }; 
Number.prototype.bytes32sw = function() { return [this & 0xff, (this >>> 8) & 0xff, (this >>> 16) & 0xff, (this >>> 24) & 0xff]; }; 
Number.prototype.bytes16 = function() { return [(this >>> 8) & 0xff, this & 0xff]; }; 
Number.prototype.bytes16sw = function() { return [this & 0xff, (this >>> 8) & 0xff]; }; 

Array.prototype.adler32 = function (start, len) { 
    switch (arguments.length) { case 0: start = 0; case 1: len = this.length - start; } 
    var a = 1, b = 0; 
    for (var i = 0; i < len; i++) { 
     a = (a + this[start + i]) % 65521; b = (b + a) % 65521; 
    } 
    return ((b << 16) | a).toUInt(); 
}; 

Array.prototype.crc32 = function (start, len) { 
    switch (arguments.length) { case 0: start = 0; case 1: len = this.length - start; } 
    var table = arguments.callee.crctable; 
    if (!table) { 
     table = []; 
     var c; 
     for (var n = 0; n < 256; n++) { 
      c = n; 
      for (var k = 0; k < 8; k++) 
       c = c & 1 ? 0xedb88320^(c >>> 1) : c >>> 1; 
      table[n] = c.toUInt(); 
     } 
     arguments.callee.crctable = table; 
    } 
    var c = 0xffffffff; 
    for (var i = 0; i < len; i++) 
     c = table[(c^this[start + i]) & 0xff]^(c >>> 8); 

    return (c^0xffffffff).toUInt(); 
}; 


var createPNG = function (canvasid) { 
var imageData = Array.prototype.slice.call(canvasid.getContext("2d").getImageData(0, 0, canvasid.width, canvasid.height).data); 
var w = canvasid.width; 
var h = canvasid.height; 
var stream = [ 
        0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 
        0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52 
      ]; 
Array.prototype.push.apply(stream, w.bytes32()); 
Array.prototype.push.apply(stream, h.bytes32()); 
stream.push(0x08, 0x06, 0x00, 0x00, 0x00); 
Array.prototype.push.apply(stream, stream.crc32(12, 17).bytes32()); 
var len = h * (w * 4 + 1); 
for (var y = 0; y < h; y++) 
    imageData.splice(y * (w * 4 + 1), 0, 0); 
var blocks = Math.ceil(len/32768); 
Array.prototype.push.apply(stream, (len + 5 * blocks + 6).bytes32()); 
var crcStart = stream.length; 
var crcLen = (len + 5 * blocks + 6 + 4); 
stream.push(0x49, 0x44, 0x41, 0x54, 0x78, 0x01); 
for (var i = 0; i < blocks; i++) { 
    var blockLen = Math.min(32768, len - (i * 32768)); 
    stream.push(i == (blocks - 1) ? 0x01 : 0x00); 
    Array.prototype.push.apply(stream, blockLen.bytes16sw()); 
    Array.prototype.push.apply(stream, (~blockLen).bytes16sw()); 
    var id = imageData.slice(i * 32768, i * 32768 + blockLen); 
    Array.prototype.push.apply(stream, id); 
} 
Array.prototype.push.apply(stream, imageData.adler32().bytes32()); 
Array.prototype.push.apply(stream, stream.crc32(crcStart, crcLen).bytes32()); 

stream.push(0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44); 
Array.prototype.push.apply(stream, stream.crc32(stream.length - 4, 4).bytes32()); 
return "data:image/png;base64," + btoa(String.fromCharCode.apply(null, stream)); 
}; 



//code here for bmpbase64 from canvas: 
var encodeData = function(data) { 
    var strData = ""; 
    if (typeof data == "string") { 
     strData = data; 
    } else { 
     var aData = data; 
     for (var i=0;i<aData.length;i++) { 
      strData += String.fromCharCode(aData[i]); 
     } 
    } 
    return btoa(strData); 
} 

// creates a base64 encoded string containing BMP data 
// takes an imagedata object as argument 
var createBMP = function(oData) { 
    var aHeader = []; 

    var iWidth = oData.width; 
    var iHeight = oData.height; 

    aHeader.push(0x42); // magic 1 
    aHeader.push(0x4D); 

    var iFileSize = iWidth*iHeight*3 + 54; // total header size = 54 bytes 
    aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize/256); 
    aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize/256); 
    aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize/256); 
    aHeader.push(iFileSize % 256); 

    aHeader.push(0); // reserved 
    aHeader.push(0); 
    aHeader.push(0); // reserved 
    aHeader.push(0); 

    aHeader.push(54); // dataoffset 
    aHeader.push(0); 
    aHeader.push(0); 
    aHeader.push(0); 

    var aInfoHeader = []; 
    aInfoHeader.push(40); // info header size 
    aInfoHeader.push(0); 
    aInfoHeader.push(0); 
    aInfoHeader.push(0); 

    var iImageWidth = iWidth; 
    aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth/256); 
    aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth/256); 
    aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth/256); 
    aInfoHeader.push(iImageWidth % 256); 

    var iImageHeight = iHeight; 
    aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight/256); 
    aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight/256); 
    aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight/256); 
    aInfoHeader.push(iImageHeight % 256); 

    aInfoHeader.push(1); // num of planes 
    aInfoHeader.push(0); 

    aInfoHeader.push(24); // num of bits per pixel 
    aInfoHeader.push(0); 

    aInfoHeader.push(0); // compression = none 
    aInfoHeader.push(0); 
    aInfoHeader.push(0); 
    aInfoHeader.push(0); 

    var iDataSize = iWidth*iHeight*3; 
    aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize/256); 
    aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize/256); 
    aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize/256); 
    aInfoHeader.push(iDataSize % 256); 

    for (var i=0;i<16;i++) { 
     aInfoHeader.push(0); // these bytes not used 
    } 

    var iPadding = (4 - ((iWidth * 3) % 4)) % 4; 

    var aImgData = oData.data; 

    var strPixelData = ""; 
    var y = iHeight; 
    do { 
     var iOffsetY = iWidth*(y-1)*4; 
     var strPixelRow = ""; 
     for (var x=0;x<iWidth;x++) { 
      var iOffsetX = 4*x; 

      strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+2]); 
      strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+1]); 
      strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX]); 
     } 
     for (var c=0;c<iPadding;c++) { 
      strPixelRow += String.fromCharCode(0); 
     } 
     strPixelData += strPixelRow; 
    } while (--y); 

    var strEncoded = encodeData(aHeader.concat(aInfoHeader)) + encodeData(strPixelData); 

    return "data:image/bmp;base64,"+strEncoded; 
} 


// BMPbase64 usage onload 
    var canvasbmp = document.getElementById("canvasbmp"); 
    var ctxbmp = canvasbmp.getContext("2d"); 
     ctxbmp.fillStyle="#FF0000";//fill color in to canvas here.. 
     ctxbmp.fillRect(0,0,170,100); 
    var imagedata= ctxbmp.getImageData(0, 0, canvasbmp.width, canvasbmp.height); 
    var bmpbase64data=createBMP(imagedata);//it will returns me the bmpbase64 data. 


    document.getElementById("testimagebmp").src =bmpbase64data; 


// pngbase64 usage onload 

var canvaspng = document.getElementById("canvaspng"); 
     var ctxpng = canvaspng.getContext("2d"); 
      ctxpng.fillStyle="#FF0000";//fill color in to canvas here.. 
      ctxpng.fillRect(0,0,170,100); 
     var imagedata= ctxpng.getImageData(0, 0, canvaspng .width, canvaspng.height); 
     var pngbase64data= createPNG(imagedata);//it will returns me the pngbase64 data. 
document.getElementById("testimagepng").src =pngbase64data; 

//html code here 
    <canvas id="canvasbmp" width="200" height="100" style="border:2px solid #c3c3c3;"></canvas> 
    <canvas id="canvaspng" width="200" height="100" style="border:2px solid #c3c3c3;"></canvas> 

    <img id="testimagebmp" width="200" height="100" style="border:2px solid #c3c3c3;" /> 
    <img id="testimagepng" width="200" height="100" style="border:2px solid #c3c3c3;" /> 
相關問題