12.14 HTML Canvas图像导出

将画布图像数据保存为一个HTML图像元素

到目前为止,我们在画布中绘制的图形都仅限于在画布中使用,而无法在其他位置使用。这实际上是不理想的,特别是如果你希望导出漂亮的画布绘图作品,并将他保存在其他位置。其实画布还有一个很有用的toDataURL方法,这个简单的方法能够将画布绘图转换为一个数据URL,我们可以通过它在浏览器上显示一个图像。

注意:Mozilla Firefox浏览器本身支持右键单击canvas元素,然后将它另存为图像。它所使用的方法与在代码中使用toDataURL是完全相同的。

这个方法实际上是很简单的,所以下面马上使用这个方法来导出一个基本图形,后面会详细讲述它的工作原理。

context.save(); 
context.fillRect(50, 50, 100, 100); 
context.fillStyle = "rgb(255, 0, 0)"; 
context.fillRect(100, 100, 100, 100); 
context.restore();
context.fillRect(150, 150, 100, 100); 
var dataURL = canvas.get(0).toDataURL(); 

这段代码将绘制一系列相互叠加的正方形,然后将图像数据URL赋值给dataURL变量。你会看到这三个正方形在浏览器的显示效果(参见图1),但是现在它仍然是画布图像,而不是导出的图像。下面介绍如何显示导出的图像。

准备将要导出的画布

这个例子中最关键的部分是dataURL变量,下面是你刚刚存储到此变量中的值的一个片段:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAYAAADL1t
+KAAAXvElEQVR4Ae3XQQ4dNxYDwPkD3//KPZMDRItA0ovI8tINS81iG8T/fd/3H38IECBAgACBtwX++/
bre3sCBAgQIEDgLwGD7jsgQIAAAQIBAgY9oEQRCBAgQICAQfcNECBAgACBAAGDHlCiCAQIECBAwKD7
BggQIECAQICAQQ8oUQQCBAgQIGDQfQMECBAgQCBAwKAHlCgCAQIECBAw6L4BAgQIECAQIG
DQA0oUgQABAgQIGHTfAAECBAgQCBAw6AElikCAAAECBAy6b4AAAQIECAQIGPSAEkUgQIAAAQIG
3TdAgAABAgQCBAx6QIkiECBAgAABg+4bIECAAAECAQIGPaBEEQgQIECAgEH3DRAgQIAAgQABgx5QoggECBAgQMCg… 

实际的输出比这些要长得多,但是实际上只有前面4个单词是我们现在关心的。前面3个单词是data:image/png;它们表示后续内容是一个PNG格式的图像的数据URL。第4个单词是base64,它表示数据采用base64编码格式。这种格式经常用于向使用文本数据的系统传输二进制数据(例如图像)。实际上,在base64后面的所有数字、字母和符号是以文本表示的画布图像。

注意:Canvas规范支持使用toDataURL方法导出其他类型的图像,然而,PNG支持是默认的要求,而各个浏览器制造商可以自行决定是否支持其他格式的图像。

这是一个不寻常的做法,但是如果复制dataURL变量中的字符串,然后粘贴到现代浏览器的地址栏(只要不超过输入URL长度限制),那么你就会看到在画布中绘制的图像。然后,在需要时,可以右键单击图像,将它保存到桌面。或者,你可以在例子中用生成的图像替换canvas元素:

var dataURL = canvas.get(0).toDataURL(); 
var img = $("<img></img>"); 
img.attr("src", dataURL); 
canvas.replaceWith(img);

这段代码使用jQuery创建了一个全新的HTML img元素,然后将图像数据赋值给它的src属性。最后,使用jQuery的replaceWith方法将canvas元素替换成刚刚创建的img元素。这样,我们就得到一个图像,其内容与画布上绘制的内容完全相同。你可以通过右键单击图像,然后查看是否有“图片另存为…”或类似选项,从而确定它是否真是一个图像(参见图2)。

将保存的画布图像数据保存为一个HTML图像元素
注意:需要指出的是,base64数据比它表示的原始二进制图像数据大50%。如果你处理的是少量较小的图像,那么这就不是问题,但是如果你处理的是大图像和大量图像,它就会有一些问题。

实际上,你可以自由决定如何使用这些图像数据,但是首先需要知道如何将画布导出为图像。你甚至可以使用画布随意绘制一个图像,然后导出图像,使用它作为CSS背景。