javascript 将文本放在图像上并另存为图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18770039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 13:10:27  来源:igfitidea点击:

Put text on an image and save as image

javascripthtmlimagecanvas

提问by milan

I have one problem with HTML5 Canvas. I have one image. On this image I want to put text and display/save this as an image.

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

I have this code:

我有这个代码:

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"; 
};

This works fine. There is my image and the text on it. But it is still a canvas and no image. Can anybody help me?

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

回答by markE

For security reasons, there's no convenient way of saving a canvas drawing to a user's local drive.

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

As a workaround, go "old school": Convert the canvas to an image and display it in a new window.

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

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"; 
};

回答by milan

Sand boxing

沙拳

Browsers are sand-boxed when it deals with saving content to user's hard disk. This is for security (you don't want a bad hacker (or spy) to overwrite system files or plant a virus or a backdoor etc.). So direct access is prevented and local storage is isolated.

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

You always need to "bridge" the content by an user interaction that approves the operation and therefor the browser will request you to choose a location for the file by popping up a dialog to make the user aware of that the browser tries to deliver content to be saved (see demo below).

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

Invoking save dialogs

调用保存对话框

Here are a couple of other possibilities to enable download.

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

If a link for example under the image is ok then you can do:

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

/// 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);

The download attribute is a new HTML5 feature. Instead of "navigating" to this location the browser will show a save dialog instead and let the user save its content to disk.

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

You can also automate the whole clicking feature by generating an event for it.

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

For example:

例如:

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");
    }
}

Saving to server

保存到服务器

You can always go by the step of saving the file to a server. However, you will also have to go through the save dialog step when retrieving the file from server (the dialog).

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

If you want to store the file only to be shown in the browser this is perfect.

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

There are various ways to do this (there are many solutions on SO for this).

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

Local storage

本地存储

And a different option is to store the file in the browser's local storage. You have Web Storage, however this is very limited (typically between 2.5 - 5 mb) and considering that each char stored takes two bytes the actual storage is just half of that (it can only store strings such as the data-uri and data-uris is about 33% larger than the original file). But if you save small icons, sprites etc. this might do.

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

In addition you can use Indexed DB(and the now deprectaed Web SQL) which can store larger data and you can also request user's permission to store x mb of dat.

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

The same goes with File API(which is currently only implemented in Chrome). This acts more like a file system and is intended to store huge files.

这同样与文件API(这是目前仅适用于Chrome实现)。这更像是一个文件系统,旨在存储大文件。

These might seem more complex if you are not familiar with them, but I mention them as possible options as these also saves you bandwidth communicating with a server and you move the "burden" to the client instead of the server.

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