як зберегти полотно як зображення у форматі PNG?


80

У мене є елемент полотна з кресленням, і я хочу створити кнопку, яка при натисканні збереже зображення як файл у форматі PNG. Отже, воно має відкрити діалогове вікно збереження, відкриття, закриття ...

Я роблю це за допомогою цього коду

var canvas = document.getElementById("myCanvas");
window.open(canvas.toDataURL("image/png"));

Але коли я тестую це в IE9, відкривається нове вікно із повідомленням "веб-сторінка не може відображатися", а її URL-адреса:

дані: image / png; base64,iVBORw0KGgoAAAANSUhEUgAAAmAAAABpCAYAAACd + 58xAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAADRwSURBVHhe7V0HgBVF0q7ZJSlJwRxAPUFRD39RFLN34qGnnomoqIjhzBlFPROIgsoZzogR5AQEzJ4BPFAUEUwgJjgQkCQKooggaf / 6el6 / 6ZnpSW / zUn237u5MdXX1172 + z6rqaqeEG6VsJet + PDW / vkdrfx3H3yfT2tVzaP26X6hkw1q / Boei / 280 / 29JwznZxJPUyXtBQBAQBAQBQaBcECjefmi56BWlZYtAeqajx / WokfrJYEqOIikOFRfXoVq161PtOk2odu0t + ectqKiojnrntWhC46QhYOtXfUarl79Ivy9 / ldau + Н + Тх / 8b2SbjJ07pWFQy2Uqnp2yXSrQJAoKAICAICALJCAgBS8ao8iTi / UvpSZlBxiwqwWOKimsxCWtEdettR3XqbEfFtRonkrBYArZh3fe0 + senadWyEbRm1UzasP53K45ZiFc84RKyVXkbVUYWBAQBQUAQyIqAELCsiFW2fDQpSyZk8UQMMysqKmaPWCOqt8mOVK / eTuQU1YuccCQBW7dyIq38 / j5a / ДГ / ad3a5QGXmqsvLfGKJl0ZCFdONEOPyl5lGV8QEAQEAUGghiMgBKzqLHCeHqVOrILtduF4MpZExEqoVq167A3bmjap34J / bmoFqcj2dM3Pr9GK + b1p5bJXmXz9nEC + 3FiorYF4hcmXlo + gUrk + um / + e + QoVWfxxRJBQBAQBAQBQUAQqBwE8uzCwiMiaEqOWYR5jJ2 / 6Hl58nYHk0Pr1v1Ov62cTytXfE5r1yyyc6RgDhI16 + L + tLqFZ9xnteGUKc0Xi876YpYkFDCfpqFEz9YGpRERhAQBAQBQaB8ERAPWPnim157JreX6 / eK7eJ / Ge0RS8oPc9gT1pTqN2jFocltfdPxecBU2HHxgBTky + 71CjPGCO + YyU4j0TU9ZcGf0y + JSAoCgoAgIAgIAoJATUcgG2dQ0jpKZ / Xp + PlLtEcs3huGQhO / r17K3rBvuGrEUt8i5HPAkHC / Yt6lKuwYKiuRM9TtGbY0rcerTBLwC / KY1fSNJ / MTBAQBQUAQqAwExANWGaiHx0z2aJl9CknET + MRc2XsVSKKaNP6O1CDhvtwYn5dJZf3gOG0IxLuS0e + LB4vw9sVhiwmHywmF6xqLLdYIQgIAoKAICAICAJVAQHTo2XmkNtzv6K5R7RXLOwRs3MaW + 47SNkG9oRxZQmun6qbImCo84VSE + 5pR3 / zvFZJni / 7e8tTHiCeqCkAqsKKig2CgCAgCAgCgoAgUG0RCBKzMLmwkzHdL4pk4XlUAn7Uu3XrVtPqVfO4lurPSq0KQa5cdAv9snBgqM5XFPlKSsSPM8o3mcxES2hZtf0rEMMFAUFAEKiBCEgIsqotavpk / OiwZViHPQk / LgHfHo5EnbCGjVpxeYo9yNmw9oeSn2YeTatWTPNzozzX8ZOeWPJlJVRJnrOoxUtJtmLEUmqoartH7BEEBAFBQBCoJggIASu / hUqkUokC2rZkwSSCBU12wpadhNXbpAk13vwwKlJ3O / L1QmYrxPNlDxuGyVtyIn6K8KSZHwY3XsRX + W0L0VyTEPjwM6KuFxN1uiB6Vkv48MpdjxLt9ieieQvscuvWE13eh2jnQ9zv + F2aICAICAKCQGEIRH22559H5IqnDTMGeU / SgUJ7WNLjOVH9g8 / Xrv2Fa4P9SM6K7y4t + WXRw76sfVc42fPV936iJ5 + LKrbqTU0P3rA + 0dZbEh20L9HJHYj23I2oVrHFT5U5NFnY4m6svUA0Pvo8efbvjCBqtr0nN + IVot4Dkvv1v5aoy / HJcpUpsfI3olffdknV0uWuJfv9kWjkw55VIFAfM073PE4EkqZbEBf9HMTs8C6e3KhHiPbdqzJnKWMLAoJAeSMgHrDyRrj0 + rOEGvVoYY9Y0inIeE + YQQ + cqGGj3dgDtvJjC / mKm7BHmG68lGjO + 0T

Хтось знає, як це виправити?


можливий дублікат How to save svg canvas to local file system
Philipp

Відповіді:


66

спробуйте це:

var c=document.getElementById("alpha");
var d=c.toDataURL("image/png");
var w=window.open('about:blank','image from canvas');
w.document.write("<img src='"+d+"' alt='from canvas'/>");

Це відображає зображення з полотна на новій сторінці, але якщо у вас є open popup in new tabналаштування, воно відображається about:blankв адресному рядку.

EDIT: - хоча window.open("<img src='"+ c.toDataURL('image/png') +"'/>")не працює в FF або Chrome, наступні роботи, хоча рендеринг дещо відрізняється від того, що показано на полотні, я думаю, що проблема в прозорості:

window.open(c.toDataURL('image/png'));

він виходить з ладу за цією командою: var w = window.open ('about: blank', 'image from canvas');
підлий

4
я змінив його на такий: var w = window.open ('about: blank') ;, і тепер зображення відкривається в новому вікні, але як отримати його так, щоб його поле збереження було закритим, я не хочу клацнути правою кнопкою миші на зображенні та натиснути "Зберегти як ..."
підлий

31

FileSaver.js повинен вам допомогти тут.

var canvas = document.getElementById("my-canvas");
// draw to canvas...
canvas.toBlob(function(blob) {
    saveAs(blob, "pretty image.png");
});

13
У IE9 є багато чого, що не працює :-( Досить багато можна виправити за допомогою поліфілів, але я боюся, що це виходить за рамки цього. Якщо ви можете, я пропоную використовувати Google Chrome Frame для користувачів, які використовують IE.
Моріс

@VagueExplanation toBlob () не підтримується в Safari. Але простий поліфіл можна знайти тут: developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/…
Моріс

18

Я використав це рішення для встановлення імені файлу :

HTML:

<a href="#" id="downloader" onclick="download()" download="image.png">Download!</a>
<canvas id="canvas"></canvas>

JavaScript:

function download(){
    document.getElementById("downloader").download = "image.png";
    document.getElementById("downloader").href = document.getElementById("canvas").toDataURL("image/png").replace(/^data:image\/[^;]/, 'data:application/octet-stream');
}

12

У мене була ця проблема, і це найкраще рішення без будь-яких зовнішніх або додаткових бібліотек сценаріїв: У тегах або файлах Javascript створіть цю функцію: тут ми припускаємо, що canvas - це ваше полотно:

function download(){
        var download = document.getElementById("download");
        var image = document.getElementById("canvas").toDataURL("image/png")
                    .replace("image/png", "image/octet-stream");
        download.setAttribute("href", image);

    }

У тілі HTML-коду вкажіть кнопку:

<a id="download" download="image.png"><button type="button" onClick="download()">Download</button></a>

Це працює, і посилання для завантаження виглядає як кнопка. Перевірено у Firefox та Chrome.


1
На жаль, в IE 11 він очищає екран і змінює URL-адресу на: data: image / octet-stream; base64, iVBORw
Mike

10

Щоб вмістити всі три пункти:

  • кнопку
  • зберегти зображення у форматі png
  • відкрити діалогове вікно збереження, відкриття, закриття

Діалогове вікно файлу - це параметр у браузері.

Для кнопки / збереження частини призначте наступну функцію, виведену з інших відповідей, на ваші кнопки на клацанні:

function DownloadCanvasAsImage(){
    let downloadLink = document.createElement('a');
    downloadLink.setAttribute('download', 'CanvasAsImage.png');
    let canvas = document.getElementById('myCanvas');
    let dataURL = canvas.toDataURL('image/png');
    let url = dataURL.replace(/^data:image\/png/,'data:application/octet-stream');
    downloadLink.setAttribute('href', url);
    downloadLink.click();
}

Приклад на Codepen

Інший, дещо чистіший підхід - використання Canvas.toBlob () :

function DownloadCanvasAsImage(){
    let downloadLink = document.createElement('a');
    downloadLink.setAttribute('download', 'CanvasAsImage.png');
    let canvas = document.getElementById('myCanvas');
    canvas.toBlob(function(blob) {
      let url = URL.createObjectURL(blob);
      downloadLink.setAttribute('href', url);
      downloadLink.click();
    });
}

Приклад на Codepen

Жодне з рішень не є 100% сумісним для переглядачів, тому перевірте клієнта


Після СТІЛЬКОГО часу, що шукав рішення, це саме для мене спрацювало. У Firefox 76.0.1 (64-розрядна версія), що я і використовую. Мені слід перевірити інші браузери, але я сподіваюся, що щось оновлене все одно буде працювати.
Алан Стюарт,

4

Можливо, я знайшов кращий спосіб не змушувати користувача клацати правою кнопкою миші та "зберігати зображення як". У прямому ефірі намалюйте код canvas base64 у hrefпосиланні та змініть його, щоб завантаження розпочалося автоматично. Я не знаю, чи сумісний він із браузером, але він повинен працювати з основними / новими браузерами .

var canvas = document.getElementById('your-canvas');
    if (canvas.getContext) {
        var C = canvas.getContext('2d');
    }

$('#your-canvas').mousedown(function(event) {
    // feel free to choose your event ;) 

    // just for example
    // var OFFSET = $(this).offset();
    // var x = event.pageX - OFFSET.left;
    // var y = event.pageY - OFFSET.top;

    // standard data to url
    var imgdata = canvas.toDataURL('image/png');
    // modify the dataUrl so the browser starts downloading it instead of just showing it
    var newdata = imgdata.replace(/^data:image\/png/,'data:application/octet-stream');
    // give the link the values it needs
    $('a.linkwithnewattr').attr('download','your_pic_name.png').attr('href',newdata);

});

Ви можете обернути <a>все, що завгодно.


0

Спробуйте це:

jQuery('body').after('<a id="Download" target="_blank">Click Here</a>');

var canvas = document.getElementById('canvasID');
var ctx = canvas.getContext('2d');

document.getElementById('Download').addEventListener('click', function() {
    downloadCanvas(this, 'canvas', 'test.png');
}, false);

function downloadCanvas(link, canvasId, filename) {
    link.href = document.getElementById(canvasId).toDataURL();
    link.Download = filename;
}

Ви можете просто помістити цей код у консоль у firefox або chrom і після того, як змінили ідентифікатор тегу полотна у цьому вищезазначеному сценарії, і запустити цей скрипт у консолі.

Після запуску цього коду ви побачите посилання у вигляді тексту "натисніть тут" внизу сторінки html. натисніть на це посилання та відкрийте малюнок на полотні як зображення у форматі PNG у новому вікні збережіть зображення.


0

Надішліть форму, що містить вхідні дані зі значенням полотна, доDataURL ('image / png') наприклад

// JAVASCRIPT

    var canvas = document.getElementById("canvas");
    var url = canvas.toDataUrl('image/png');

Вставте значення url у свій прихований ввід для елемента форми.

// PHP

    $data = $_POST['photo'];
    $data = str_replace('data:image/png;base64,', '', $data);
    $data = base64_decode($data);
    file_put_contents("i".  rand(0, 50).".png", $data);

Це працює добре, за винятком того, що canvas.toDataUrl(...)повинна бути функція JavaScript canvas.toDataURL(...).
Бреннон,

0

Повний робочий HTML-код . Вирізати + Вставити у новий файл .HTML:

Містить два приклади:

  1. Полотно у файлі HTML.
  2. Полотно, динамічно створене за допомогою Javascript.

Перевірено в:

  1. Chrome
  2. Internet Explorer
  3. * Край (назва заголовка не відображається)
  4. Firefox
  5. Опера

<!DOCTYPE HTML >
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title> #SAVE_CANVAS_TEST# </title>
    <meta 
        name   ="author" 
        content="John Mark Isaac Madison"
    >
    <!-- EMAIL: J4M4I5M7 -[AT]- Hotmail.com -->
</head>
<body>

<div id="about_the_code">
    Illustrates:
    <ol>
    <li>How to save a canvas from HTML page.     </li>
    <li>How to save a dynamically created canvas.</li>
    </ol>
</div>

<canvas id="DOM_CANVAS" 
        width ="300" 
        height="300"
></canvas>

<div id="controls">
    <button type="button" style="width:300px;"
            onclick="obj.SAVE_CANVAS()">
        SAVE_CANVAS ( Dynamically Made Canvas )
    </button>

    <button type="button" style="width:300px;"
            onclick="obj.SAVE_CANVAS('DOM_CANVAS')">
        SAVE_CANVAS ( Canvas In HTML Code )
    </button>
</div>

<script>
var obj = new MyTestCodeClass();
function MyTestCodeClass(){

    //Publically exposed functions:
    this.SAVE_CANVAS = SAVE_CANVAS;

    //:Private:
    var _canvas;
    var _canvas_id = "ID_OF_DYNAMIC_CANVAS";
    var _name_hash_counter = 0;

    //:Create Canvas:
    (function _constructor(){
        var D   = document;
        var CE  = D.createElement.bind(D);
        _canvas = CE("canvas");
        _canvas.width = 300;
        _canvas.height= 300;
        _canvas.id    = _canvas_id;
    })();

    //:Before saving the canvas, fill it so
    //:we can see it. For demonstration of code.
    function _fillCanvas(input_canvas, r,g,b){
        var ctx = input_canvas.getContext("2d");
        var c   = input_canvas;

        ctx.fillStyle = "rgb("+r+","+g+","+b+")";
        ctx.fillRect(0, 0, c.width, c.height);
    }

    //:Saves canvas. If optional_id supplied,
    //:will save canvas off the DOM. If not,
    //:will save the dynamically created canvas.
    function SAVE_CANVAS(optional_id){

        var c = _getCanvas( optional_id );

        //:Debug Code: Color canvas from DOM
        //:green, internal canvas red.
        if( optional_id ){
            _fillCanvas(c,0,255,0);
        }else{
            _fillCanvas(c,255,0,0);
        }

        _saveCanvas( c );
    }

    //:If optional_id supplied, get canvas
    //:from DOM. Else, get internal dynamically
    //:created canvas.
    function _getCanvas( optional_id ){
        var c = null; //:canvas.
        if( typeof optional_id == "string"){
            var id = optional_id;
            var  d = document;
            var c  = d.getElementById( id );
        }else{
            c = _canvas; 
        }
        return c;
    }

    function _saveCanvas( canvas ){
        if(!window){ alert("[WINDOW_IS_NULL]"); }

        //:We want to give the window a unique
        //:name so that we can save multiple times
        //:without having to close previous
        //:windows.
        _name_hash_counter++              ; 
        var NHC = _name_hash_counter      ;
        var URL = 'about:blank'           ;
        var name= 'UNIQUE_WINDOW_ID' + NHC;
        var w=window.open( URL, name )    ;

        if(!w){ alert("[W_IS_NULL]");}

        //:Create the page contents,
        //:THEN set the tile. Order Matters.
        var DW = ""                        ;
        DW += "<img src='"                 ;
        DW += canvas.toDataURL("image/png");
        DW += "' alt='from canvas'/>"      ;
        w.document.write(DW)               ;
        w.document.title = "NHC"+NHC       ;

    }

}//:end class

</script>

</body>
<!-- In IE: Script cannot be outside of body.  -->
</html>

0

Мені дуже подобається відповідь Tovask, але вона не працює через функцію, що має ім'я download( ця відповідь пояснює, чому). Я також не бачу сенсу замінювати "data: image / ..." на "data: application / ...".

Наступний код був протестований у Chrome та Firefox і, здається, чудово працює в обох.

JavaScript:

function prepDownload(a, canvas, name) {
    a.download = name
    a.href = canvas.toDataURL()
}

HTML:

<a href="#" onclick="prepDownload(this, document.getElementById('canvasId'), 'imgName.png')">Download</a>
<canvas id="canvasId"></canvas>

-1
var canvasId = chart.id + '-canvas';
var canvasDownloadId = chart.id + '-download-canvas';
var canvasHtml = Ext.String.format('<canvas id="{0}" width="{1}" height="{2}"></canvas><a id="{3}"/>',
canvasId,
chart.getWidth(),
chart.getHeight(),
canvasDownloadId);
var canvasElement = reportBuilder.add({ html: canvasHtml });

var canvas = document.getElementById(canvasId);

var canvasDownload = document.getElementById(canvasDownloadId);
canvasDownload.href = chart.getImage().data;
canvasDownload.download = 'chart';

canvasDownload.click();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.