問題
先前在項(xiàng)目中用d3畫了樹圖等svg圖形,然后需求是需要以png格式上傳這個(gè)圖片到服務(wù)器保存以供其他地方調(diào)用,可以先生成svg碼流,然后在canvas上繪圖绑青,最后在利用canvas.toDataUrl()生成png碼流,然后上傳到服務(wù)器屋群,但是上傳后發(fā)現(xiàn)一個(gè)問題就是png碼流生成的圖片丟失了canvas的背景色时迫,背景色變?yōu)榱送该鞯摹?/p>
問題原因
查詢問題后在canvas草案中發(fā)現(xiàn)原因是:
For image types that do not support an alpha channel, the image must be composited onto a solid black background using the source-over operator, and the resulting image must be the one used to create the data: URL.
當(dāng)你利用toDataUrl輸出的碼流生成圖片時(shí)候,根據(jù)圖片格式不同會(huì)是透明或者黑色谓晌。
解決方案
直接上代碼:
//Returns contents of a canvas as a png based data url, with the specified
//background color
function canvasToImage(backgroundColor)
{
//cache height and width
var w = canvas.width;
var h = canvas.height;
var data;
if(backgroundColor)
{
//get the current ImageData for the canvas.
data = context.getImageData(0, 0, w, h);
//store the current globalCompositeOperation
var compositeOperation = context.globalCompositeOperation;
//set to draw behind current content
context.globalCompositeOperation = "destination-over";
//set background color
context.fillStyle = backgroundColor;
//draw background / rect on entire canvas
context.fillRect(0,0,w,h);
}
//get the image data from the canvas
var imageData = this.canvas.toDataURL("image/png");
if(backgroundColor)
{
//clear the canvas
context.clearRect (0,0,w,h);
//restore it with original / cached ImageData
context.putImageData(data, 0,0);
//reset the globalCompositeOperation to what it was
context.globalCompositeOperation = compositeOperation;
}
//return the Base64 encoded data url string
return imageData;
}
主要幾個(gè)步驟
- 從canvas中得到ImageData
- 將globalCompositeOperation屬性設(shè)置為destination-over. 然后將會(huì)在當(dāng)前圖形之下繪制新的圖形
- 畫一個(gè)rectangle填充你想要的背景色
- 此時(shí)再生成碼流
- 后面就是清除canvas恢復(fù)到最初狀態(tài)即可