HTML5 画布转 PNG 文件

Posted

技术标签:

【中文标题】HTML5 画布转 PNG 文件【英文标题】:HTML5 Canvas to PNG File 【发布时间】:2012-09-29 13:50:24 【问题描述】:

我正在尝试将 html5 画布转换为图像。这是我到目前为止得到的:

var tmp_canvas = document.getElementById('canvas');
var dataURL = tmp_canvas.toDataURL("image/png");
$('#thumbnail_list').append($('<img/>',  src : dataURL ).addClass('image'));

但问题是我得到了这个代码:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAEsCAYAAADtt+XCAAAgAElEQVR4nNS6Z1xVaZbvv/c+CVOZc6mYEMlJMZRizgljGRARs6AgOSMGQATBSM5ZyTkoOQkSzJWrp3t6etLt6Z7pmf/c++L7f3EOiBZW2dM9dz73xfdzztl7n3Oe/Txrrd9a69mCTC4gkwvIZAKSTECUBARRQBA+jii+46f.......class="image">

我想要一个用户可以下载的普通图片路径!

有什么帮助吗?

【问题讨论】:

您得到的是该画布到图像的 base64 表示,我认为您必须将其转换为字节,然后将这些字节保存到您想要的图像文件中。 您可以添加一个简单的提示来告诉用户右键单击生成的缩略图并点击“目标另存为” 【参考方案1】:

信息: IE10+ 根本不支持以下方法。其他人已经完成了这项工作并实施了跨浏览器解决方案。 This 就是其中之一。

首先,将生成的数据 URL 添加到 &lt;a&gt; 标记的 href 属性中。 但是在某些浏览器上,仅此一项不会触发下载。相反,它将在新页面中打开链接的图像。

base64 图像的下载对话框:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...." class="image" />

根据上面的例子,将数据 URL 的 MIME 类型转换为:

<a href="data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUg....">Download</a>

通过告诉浏览器数据是application/octet-stream,它会要求你把它保存在你的硬盘上。


指定文件名:

正如Adi 在下面的 cmets 中所说,没有使用此方法定义文件名的标准方法。但是,有两种方法可能适用于某些浏览器。

A) Google Crome 引入的download 属性

<a download="image.png" href="...">

B) 在数据 URL 中定义 HTTP 标头headers=Content-Disposition: attachment; filename=image.png

<a href="data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=image.png;base64,iVBORw0KGgoAAAA">

这至少在某些旧版本的 Opera 中有效。 Here 是关于这个的一些讨论。

查看主要浏览器的 Bug/Feature-Tracking 系统表明,定义文件名是社区的一大愿望。也许我们会在不久的将来看到一个跨浏览器兼容的解决方案! ;)


节省 RAM 和 CPU 资源:

如果您不想让访问者浏览器的 RAM 膨胀,您还可以动态生成数据 URL:

<a id="dl" download="Canvas.png">Download Canvas</a>
function dlCanvas() 
    var dt = canvas.toDataURL('image/png');
    this.href = dt;
;
dl.addEventListener('click', dlCanvas, false);

这样,您的画布仍可能在浏览器中显示为图像文件。 如果你想增加打开一个下载对话框的概率,你应该扩展上面的函数,让它做如上所示的替换:

function dlCanvas() 
    var dt = canvas.toDataURL('image/png');
    this.href = dt.replace(/^data:image\/[^;]/, 'data:application/octet-stream');
;
dl.addEventListener('click', dlCanvas, false);

最后,添加 HTTP 标头以确保大多数浏览器都能为您提供有效的文件名! ;)


完整示例:
var canvas = document.getElementById("cnv");
var ctx = canvas.getContext("2d");

/* FILL CANVAS WITH IMAGE DATA */
function r(ctx, x, y, w, h, c) 
  ctx.beginPath();
  ctx.rect(x, y, w, h);
  ctx.strokeStyle = c;
  ctx.stroke();

r(ctx, 0, 0, 32, 32, "black");
r(ctx, 4, 4, 16, 16, "red");
r(ctx, 8, 8, 16, 16, "green");
r(ctx, 12, 12, 16, 16, "blue");

/* REGISTER DOWNLOAD HANDLER */
/* Only convert the canvas to Data URL when the user clicks. 
   This saves RAM and CPU ressources in case this feature is not required. */
function dlCanvas() 
  var dt = canvas.toDataURL('image/png');
  /* Change MIME type to trick the browser to downlaod the file instead of displaying it */
  dt = dt.replace(/^data:image\/[^;]*/, 'data:application/octet-stream');

  /* In addition to <a>'s "download" attribute, you can define HTTP-style headers */
  dt = dt.replace(/^data:application\/octet-stream/, 'data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=Canvas.png');

  this.href = dt;
;
document.getElementById("dl").addEventListener('click', dlCanvas, false);
<canvas id="cnv"  ></canvas>
<a id="dl" download="Canvas.png" href="#">Download Canvas</a>

【讨论】:

很遗憾,您不能以这种方式指定文件名。 很遗憾,它在 Safari 版本 7.0.3 (9537.75.14) Mac OS X 上不起作用 嗨@Moogs,很遗憾,我没有机会在Mac 上进行测试,但我总是很好奇;)您能否提供更多细节,例如:画布是否呈现三个彩色框?你在错误控制台上得到输出吗?你有下载对话吗?无论如何,Safari 7.0.3 刚好一岁。官方没有对 Safari 的完整 HTML5 支持 @Nippey 画布在 chrome 和 safari 上呈现相同的效果。唯一的区别是在 safari 中单击下载链接什么也不做,并且链接消失了。没有控制台错误。 这适用于我的 Chrome 和 Firefox。但是在 IE11 上完全失败(没有下载,没有显示对话框)。【参考方案2】:

您有 2 个选项(几乎都适用于所有浏览器):

1- 将数据发布到服务器: 在服务器上,您将有一个脚本来处理数据,然后告诉浏览器提示用户下载。

header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=something.png");
header("Content-Type: image/png");
echo base64_decode($_POST['imageData']);
exit;

2- 提示用户下载使用 Downloadify

<div id="clickMe"></div>

Downloadify.create( 'clickMe', 
   data: base64String,
   dataType: 'base64',
   filename: 'something.png'
);

【讨论】:

【参考方案3】:

您可以使用reimg 库将画布转换为图像对象,甚至为用户触发下载。

在页面中插入库后,只需使用以下命令: ReImg.fromCanvas(yourCanvasElement).downloadPng()

【讨论】:

【参考方案4】:

您也可以考虑使用 Concrete.js http://www.concretejs.com,它是一个轻量级的 HTML5 Canvas 框架,支持诸如此类的外围功能,包括下载。您只需这样做:

canvas.download(
  fileName: 'my-file.png'
);

你就完成了。

【讨论】:

那块画布是什么?如何创建它?它是一个具体的对象吗?它是一个 html 元素吗?如何初始化它以从您的库中获取下载功能?这是什么版本的混凝土?有 CDN 吗?

以上是关于HTML5 画布转 PNG 文件的主要内容,如果未能解决你的问题,请参考以下文章

Base64 PNG 数据到 HTML5 画布

使用 Delphi 的 HTML5 画布动画

画布 todataURL 图像 Png 质量不起作用

如何在 html5 中制作透明画布?

将 HTML 5 画布保存到 Chrome 中的文件?

如何将画布保存为html5中的图像?