Как сохранить холст как изображение с помощью canvas.toDataURL ()?

150

В настоящее время я создаю веб-приложение HTML5 / собственное приложение Phonegap, и я не могу понять, как сохранить свой холст в виде изображения с помощью canvas.toDataURL(). Кто-нибудь может мне помочь?

Вот код, что с ним не так?

// Мой холст был назван "canvasSignature"

JavaScript:


function putImage()
{
  var canvas1 = document.getElementById("canvasSignature");        
  if (canvas1.getContext) {
     var ctx = canvas1.getContext("2d");                
     var myImage = canvas1.toDataURL("image/png");      
  }
  var imageElement = document.getElementById("MyPix");  
  imageElement.src = myImage;                           

}  

HTML5:


<div id="createPNGButton">
    <button onclick="putImage()">Save as Image</button>        
</div>
Wardenclyffe
источник
5
Вопрос ОП не получил ответа. Он четко сказал, что это для Phonegap / iPad. Приведенные ответы предназначены для сохранения в настольном браузере.
tshm001
1
Не уверен насчет телефонного разговора, но я сделал это с нуля в родном iOS, используя JavaScript на другом конце, я захватываю данные .toDataURL(), а затем использую window.location, чтобы указать браузер appname://[data url]. В конце приложения UIWebView имеет метод делегата, который сообщает, следует ли загружать страницу. Я слушаю appname://и разбиваю его, когда он приходит, запрещаю загрузку страницы и фиксирую URL-адрес данных в собственной строке ... насколько вы знакомы с реальным кодом iOS / Objective C?
Дуг,

Ответы:

133

Вот код. без ошибок.

var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");  // here is the most important part because if you dont replace you will get a DOM 18 exception.


window.location.href=image; // it will save locally
user1874941
источник
1
За исключением стандартного режима IE9: «Некоторое содержимое или файлы на этой веб-странице требуют программы, которую вы не установили». Internet Explorer 8 и выше поддерживает только URI данных для изображений в CSS, <link> и <img>: developer.mozilla.org/en-US/docs/data_URIs
Cees Timmerman
45
работает отлично. как я могу изменить имя загруженного файла? идет просто «скачать» и без расширения. Благодарность!
Leabdalla
1
В Chrome это приводит к сбою браузера. Если я показываю изображение в теге изображения, оно работает, но контекстное меню отображается серым цветом, поэтому я все еще не могу сохранить изображение.
Кокодоко
Это прекрасно работает ... Но в Android (браузер по умолчанию в Galaxy S3) он просто не загружает изображение, но я получаю сообщение «Загрузка ...» навсегда.
Хабрашат
У меня есть проблема с сохранением, кто-то может помочь мне увидеть эту ссылку: stackoverflow.com/questions/25131763/…
Рамеш С.
42

Это решение позволяет изменить имя загруженного файла:

HTML:

<a id="link"></a>

JAVASCRIPT:

  var link = document.getElementById('link');
  link.setAttribute('download', 'MintyPaper.png');
  link.setAttribute('href', canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"));
  link.click();
Томас В
источник
Спасибо за это, мне это очень помогло!
Майк Мун,
23

Вы можете использовать canvas2image для запроса загрузки.

У меня была такая же проблема, вот простой пример, который добавляет изображение на страницу и заставляет браузер загружать его:

<html>
    <head>
        <script src="http://hongru.github.io/proj/canvas2image/canvas2image.js"></script>
        <script>
            function draw(){
                var canvas = document.getElementById("thecanvas");
                var ctx = canvas.getContext("2d");
                ctx.fillStyle = "rgba(125, 46, 138, 0.5)";
                ctx.fillRect(25,25,100,100); 
                ctx.fillStyle = "rgba( 0, 146, 38, 0.5)";
                ctx.fillRect(58, 74, 125, 100);
            }

            function to_image(){
                var canvas = document.getElementById("thecanvas");
                document.getElementById("theimage").src = canvas.toDataURL();
                Canvas2Image.saveAsPNG(canvas);
            }
        </script>
    </head>
    <body onload="draw()">
        <canvas width=200 height=200 id="thecanvas"></canvas>
        <div><button onclick="to_image()">Draw to Image</button></div>
        <image id="theimage"></image>
    </body>
</html>
Сколвин
источник
2
Просто попробовал, он сохранит файл без имени и расширения в Chrome.
malber
как упоминалось здесь nihilogic.dk/labs/canvas2image, установка имени файла кажется невозможной: «Было бы здорово, если бы каким-то образом имя файла могло быть прикреплено к данным, но я не нашел способа сделать это. На данный момент вам нужно указать имя файла самостоятельно. "
SColvin
1
Отправленная вами ссылка не работает
Оливер Нибро
13

Вы можете попробовать это; создать фиктивный HTML-якорь и загрузить изображение оттуда, например ...

// Convert canvas to image
document.getElementById('btn-download').addEventListener("click", function(e) {
    var canvas = document.querySelector('#my-canvas');

    var dataURL = canvas.toDataURL("image/jpeg", 1.0);

    downloadImage(dataURL, 'my-canvas.jpeg');
});

// Save | Download image
function downloadImage(data, filename = 'untitled.jpeg') {
    var a = document.createElement('a');
    a.href = data;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
}
бматову
источник
2
Мне нравится, что все было сделано на JS, включая создание элемента ссылки. Он отлично работает в целях автоматизации
Джероми Адофо
1
Идеальное решение
Хидайт Рахман
10

Я создал небольшую библиотеку, которая делает это (вместе с некоторыми другими удобными преобразованиями). Это называется reimg , и им очень просто пользоваться.

ReImg.fromCanvas(yourCanvasElement).toPng()

гиллиб
источник
Классная библиотека. Спасибо. Однако в документации к примеру есть небольшая проблема. Я открыл проблему на Github, чтобы довести ее до вашего сведения.
jmknoll
8

Эта работа для меня: (Только Google Chrome)

<html>
<head>
    <script>
            function draw(){
                var canvas = document.getElementById("thecanvas");
                var ctx = canvas.getContext("2d");
                ctx.fillStyle = "rgba(125, 46, 138, 0.5)";
                ctx.fillRect(25,25,100,100);
                ctx.fillStyle = "rgba( 0, 146, 38, 0.5)";
                ctx.fillRect(58, 74, 125, 100);
            }

            function downloadImage()
            {
                var canvas = document.getElementById("thecanvas");
                var image = canvas.toDataURL();

                var aLink = document.createElement('a');
                var evt = document.createEvent("HTMLEvents");
                evt.initEvent("click");
                aLink.download = 'image.png';
                aLink.href = image;
                aLink.dispatchEvent(evt);
            }
    </script>
</head>
<body onload="draw()">
    <canvas width=200 height=200 id="thecanvas"></canvas>
    <div><button onclick="downloadImage()">Download</button></div>
    <image id="theimage"></image>
</body>
</html>
1000Баги
источник
Возможно, вы могли бы объяснить ту часть кода, которая отвечает на вопрос, вместо того, чтобы просто вставлять ее без комментариев?
Гедиминас Масайтис 03
7

Подобен ответу 1000Bugy, но проще, потому что вам не нужно делать якорь на лету и отправлять событие щелчка вручную (плюс исправление IE).

Если вы сделаете свою кнопку загрузки якорем, вы можете взломать ее прямо перед запуском функции привязки по умолчанию. Таким образом, onAnchorClickвы можете установить привязку href к изображению base64 холста, а атрибут загрузки привязки - к тому, что вы хотите назвать своим изображением.

Это не работает в (текущем) IE, потому что он не реализует атрибут загрузки и предотвращает загрузку uris данных. Но это можно исправить, используя window.navigator.msSaveBlobвместо этого.

Таким образом , ваш якорь обработчик события клика будет как следует (где anchor, canvasи fileNameесть область применения средства поиска):

function onClickAnchor(e) {
  if (window.navigator.msSaveBlob) {
    window.navigator.msSaveBlob(canvas.msToBlob(), fileName);
    e.preventDefault();
  } else {
    anchor.setAttribute('download', fileName);
    anchor.setAttribute('href', canvas.toDataURL());
  }
}

Вот скрипка

Sjeiti
источник
2

Вместо imageElement.src = myImage;вас следует использоватьwindow.location = myImage;

И даже после этого браузер отобразит само изображение. Вы можете щелкнуть правой кнопкой мыши и использовать «Сохранить ссылку» для загрузки изображения.

Проверьте эту ссылку для получения дополнительной информации.

Хакан Серце
источник
Вау, спасибо, это действительно очень помогло :) Но как получить всплывающее окно для сохранения, чтобы кто-то мог сохранять в определенном месте (например, в папке с изображениями Android)?
Wardenclyffe
Это зависит от конкретного браузера. Браузер Android обычно загружает файлы напрямую в определенную папку.
Hakan Serce
В Chrome это работает, но контекстное меню отображается серым цветом. При попытке «перетащить» изображение из браузера Chrome вылетает.
Кокодоко
groups.google.com/a/chromium.org/forum/#!topic/blink-dev/… Открывающий URL-адрес данных, как это, похоже, будет заблокирован.
KeyOfJ
0

Вы не можете использовать ранее упомянутые методы для загрузки изображения при работе в Кордове. Вам нужно будет использовать плагин Cordova File . Это позволит вам выбрать, где его сохранить, и использовать различные параметры сохранения. Подробности здесь: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/

В качестве альтернативы вы можете преобразовать изображение в base64, а затем сохранить строку в localStorage, но это довольно быстро заполнит вашу квоту, если у вас много изображений или в высоком разрешении.

BigBalli
источник
-9

@Wardenclyffe и @SColvin, вы оба пытаетесь сохранить изображение, используя холст, а не контекст холста. оба вы должны попробовать ctx.toDataURL (); Попробуй это:

var canvas1 = document.getElementById("yourCanvasId");  <br>
var ctx = canvas1.getContext("2d");<br>
var img = new Image();<br>
img.src = ctx.toDataURL('image/png');<br>
ctx.drawImage(img,200,150);<br>

Также вы можете воспользоваться следующими ссылками:

http://tutorials.jenkov.com/html5-canvas/todataurl.html

http://www.w3.org/TR/2012/WD-html5-author-20120329/the-canvas-element.html#the-canvas-element

Винай Чандра
источник
Uncaught TypeError: объект № <CanvasRenderingContext2D> не имеет метода toDataURL.
Брэндон Оби,
1
Это неверно, поскольку у элемента контекста нет toDataURLфункции: developer.mozilla.org/en-US/docs/Web/API/… . Вы хотите вызвать toDataURLэлемент холста: developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/…
Crashalot