8

我对 HTML5 Canvas 有一个问题。我有一张图。在此图像上,我想放置文本并将其显示/保存为图像。

我有这个代码:

window.onload = function(){
 var canvas = document.getElementById("myCanvas");
 var context = canvas.getContext("2d");
 var imageObj = new Image();
 imageObj.onload = function(){
     context.drawImage(imageObj, 10, 10);
     context.font = "20px Calibri";
     context.fillText("My TEXT!", 50, 200);
 };
 imageObj.src = "mail-image.jpg"; 
};

这工作正常。有我的图片和上面的文字。但它仍然是画布,没有图像。有谁能够帮我?

4

2 回答 2

15

出于安全原因,没有方便的方法将画布绘图保存到用户的本地驱动器。

作为一种解决方法,走“老派”:将画布转换为图像并将其显示在新窗口中。

window.onload = function(){
 var canvas = document.getElementById("myCanvas");
 var context = canvas.getContext("2d");
 var imageObj = new Image();
 imageObj.onload = function(){
     context.drawImage(imageObj, 10, 10);
     context.font = "20px Calibri";
     context.fillText("My TEXT!", 50, 200);

     // open the image in a new browser tab
     // the user can right-click and save that image
     var win=window.open();
     win.document.write("<img src='"+canvas.toDataURL()+"'/>");    

 };
 imageObj.src = "mail-image.jpg"; 
};
于 2013-09-12T16:58:49.587 回答
6

沙拳

浏览器在处理将内容保存到用户硬盘时是沙盒。这是为了安全(您不希望坏黑客(或间谍)覆盖系统文件或植入病毒或后门等)。因此,直接访问被阻止,本地存储被隔离。

您始终需要通过批准操作的用户交互来“桥接”内容,因此浏览器将通过弹出一个对话框要求您选择文件的位置,以使用户知道浏览器试图将内容传递到被保存(见下面的演示)。

调用保存对话框

以下是启用下载的其他几种可能性。

如果图像下方的链接可以,那么您可以执行以下操作:

/// create an anchor/link (or use an existing)
var lnk = document.createElement('a');

/// set your image as data-uri link
lnk.href = canvas.toDataURL();

/// and the key, when user click image will be downloaded
lnk.download = 'filename.png';

/// add lnk to DOM, here after the canvas
canvas.parentElement.appendChild(lnk);

下载属性是一个新的 HTML5 特性。浏览器不会“导航”到这个位置,而是显示一个保存对话框,让用户将其内容保存到磁盘。

您还可以通过为其生成事件来自动化整个点击功能。

例如:

function download(canvas, filename) {

    if (typeof filename !== 'string' || filename.trim().length === 0)
        filename = 'Untitled';

    var lnk = document.createElement('a'),
        e;

    lnk.download = filename;        
    lnk.href = canvas.toDataURL();  

    if (document.createEvent) {

        e = document.createEvent("MouseEvents");
        e.initMouseEvent('click', true, true, window,
                         0, 0, 0, 0, 0, false, false,
                         false, false, 0, null);

        /// send event            
        lnk.dispatchEvent(e);

    } else if (lnk.fireEvent) {

        lnk.fireEvent("onclick");
    }
}

保存到服务器

您始终可以通过将文件保存到服务器的步骤进行操作。但是,从服务器(对话框)检索文件时,您还必须执行保存对话框步骤。

如果您只想存储文件以在浏览器中显示,这是完美的。

有多种方法可以做到这一点(在 SO 上有很多解决方案)。

本地存储

另一种选择是将文件存储在浏览器的本地存储中。您有Web Storage,但是这是非常有限的(通常在 2.5 - 5 mb 之间),并且考虑到每个 char 存储需要两个字节,实际存储只是其中的一半(它只能存储字符串,例如 data-uri 和 data- uris 比原始文件大 33%)。但如果你保存小图标、精灵等,这可能会。

此外,您可以使用可以存储更大数据的Indexed DB(以及现在已弃用的Web SQL),您还可以请求用户的权限来存储 x mb 的数据。

File API也是如此(目前仅在 Chrome 中实现)。这更像是一个文件系统,旨在存储大文件。

如果您不熟悉它们,这些可能看起来更复杂,但我将它们作为可能的选项提及,因为它们还可以节省您与服务器通信的带宽,并且您将“负担”转移到客户端而不是服务器。

于 2013-09-12T18:08:00.460 回答