【问题标题】:Put text on an image and save as image将文本放在图像上并另存为图像
【发布时间】:2013-09-17 04:20:07
【问题描述】:

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

这很好用。有我的图片和上面的文字。 但它仍然是画布,没有图像。 有人可以帮帮我吗?

【问题讨论】:

    标签: javascript html image canvas


    【解决方案1】:

    沙拳

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

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

    调用保存对话框

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

    如果图片下方的链接可以,那么你可以这样做:

    /// 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 之间)并且考虑到每个存储的字符需要两个字节,实际存储只是其中的一半(它只能存储诸如 data-uri 和 data 之类的字符串-uris 大约比原始文件大 33%)。但是,如果您保存小图标、精灵等,则可能会这样做。

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

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

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

    【讨论】:

    • 谢谢!这很好用。我现在使用这段代码:` var name = "..."; var canvasData = canvas.toDataURL("image/png"); var ajax = new XMLHttpRequest(); ajax.open("POST",'testSave.php',false); ajax.onreadystatechange = function() { console.log(ajax.responseText); ajax.setRequestHeader('Content-Type', 'application/upload'); ajax.send("imgData="+canvasData, "name="+name); ` 但是你怎么看,我也尝试发送一个name变量。但是这个变量我没有进入 save.php
    • Save.php 的代码:` if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) { $imageData=$GLOBALS['HTTP_RAW_POST_DATA']; $filteredData=substr($imageData, strpos($imageData, ",")+1); $unencodedData=base64_decode($filteredData); $name = $_GET["name"]; $linkname = $name.".png"; $fp = fopen("$linkname", 'wb' ); fwrite($fp, $unencodedData); fclose($fp); } ` 你能帮我得到第二个变量来命名文件吗?
    • @milan 为什么不针对这个特定问题提出一个新问题,并且会有一支军队等待帮助:)
    【解决方案2】:

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

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

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

    【讨论】:

    • 还有一个问题:是否可以将此图像自动保存在我的服务器上?
    • 是的,你可以。这是 Stackoverflow 上经常被问到的问题……例如:stackoverflow.com/questions/13198131/…
    猜你喜欢
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多