Як зберегти полотно як зображення за допомогою canvas.toDataURL ()?


141

Зараз я будую веб-додаток 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>

4
На питання ОП не отримали відповіді. Він чітко сказав, що це для Phonegap / iPad. Надані відповіді - це збереження на настільному браузері.
tshm001

1
Не впевнений у фонегапі, але я це робив з нуля в рідній iOS за допомогою JavaScript на іншому кінці, я захоплюю дані .toDataURL(), а потім використовую window.location, щоб вказати на браузер appname://[data url]. У кінці програми UIWebView має метод делегата, який говорить про те, чи слід завантажувати сторінку чи ні. Я слухаю appname://і розбиваю його, коли він заходить, забороняю завантажувати сторінку та захоплювати URL-адресу даних у рідній рядку ... наскільки ви знайомі з фактичним кодом iOS / Objective C?
Дуг

Відповіді:


121

Ось якийсь код. без жодної помилки.

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

1
За винятком режиму стандартів IE9: "Для певного вмісту або файлів на цій веб-сторінці потрібна програма, яку ви не встановили." Internet Explorer 8 і вище підтримує лише URI даних для зображень у CSS, <посилання> та <img>: developer.mozilla.org/en-US/docs/data_URIs
Cees Timmerman

45
працює чудово. як я можу змінити ім'я завантаженого файлу? це просто "скачати" і без розширення. Дякую!
Leabdalla

1
У Chrome це збій браузера. Якщо я відображую зображення в тезі зображень, воно спрацьовує, але меню правої кнопки мишіє сірим кольором - тому я все одно не можу зберегти зображення.
Кокодоко

Це чудово працює ... Але в Android (браузер за замовчуванням у Galaxy S3) він просто не завантажує зображення, але я отримую повідомлення "Завантаження ..." назавжди.
Хабрашат

У мене є проблема збереження, якась допоможе мені переглянути це посилання: stackoverflow.com/questions/25131763/…
Ramesh S

36

Це рішення дозволяє змінити ім'я завантаженого файлу:

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

Дякую за це, це мені дуже допомогло!
Майк Мун

22

Ви можете використовувати 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.
мальбер

як згадується тут nihilogic.dk/labs/canvas2image, встановити ім'я файлу не здається можливим: "Це було б дуже акуратно, якби якось ім'я файлу могло бути приєднано до даних, але я не знайшов способу зробити це. Поки що ви повинні самостійно вказати ім’я файлу. "
SColvin

1
Посилання, яке ви розмістили, порушено
Олівер Найбро

9

Ви можете спробувати це; створити фіктивний 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();
}

1
Мені подобається те, що все робилося в JS, включаючи створення елемента зв’язку. Він чудово працює для цілей автоматизації
Джеромі Адофо

Ідеальне рішення
Hidayt Rahman

8

Я створив невелику бібліотеку, яка робить це (разом із деякими іншими зручними перетвореннями). Це називається reimg , і він дійсно простий у використанні.

ReImg.fromCanvas(yourCanvasElement).toPng()


Класна бібліотека. Дякую. Однак у прикладі документації є невелика проблема. Я відкрив випуск на Github, щоб представити його вашій увазі.
jmknoll

7

Ця робота для мене: (Тільки 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>

Можливо, ви могли б пояснити ту частину свого коду, яка відповідає на питання, а не просто вставляти його без коментарів?
Gediminas Masaitis

6

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

Якщо ви зробите кнопку для завантаження якорем, ви можете встановити гарнітур перед тим, як запустити функціональну функцію якоря. Таким чином, onAnchorClickви можете встановити href з якоря на зображення зображення canvas 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());
  }
}

Ось загадка


1

Замість imageElement.src = myImage;вас слід використовуватиwindow.location = myImage;

І навіть після цього браузер відобразить саме зображення. Ви можете натиснути правою кнопкою миші та використати "Зберегти посилання" для завантаження зображення.

Перевірте це посилання для отримання додаткової інформації.


Вау, спасибі, що насправді дуже допомогло :) Але як же отримати спливаючу скриньку збереження, щоб хтось міг зберегти до певного пункту призначення (наприклад, у папці із зображеннями для Android)?
Wardenclyffe

Це залежить від конкретного браузера. Android-браузер зазвичай завантажує файли в певну папку безпосередньо для встановлення.
Хакан Серце

У Chrome це працює, але меню правою кнопкою миші затьмарене. При спробі "перетягнути" зображення з браузера Chrome виходить з ладу.
Кокодоко

groups.google.com/a/chromium.org/forum/#!topic/blink-dev/… URL-адреса для відкриття даних, подібна до цього, буде заблокована.
KeyOfJ

0

Ви не можете використовувати раніше згадані методи для завантаження зображення під час запуску в Кордові. Вам потрібно буде використовувати плагін для файлів Cordova . Це дозволить вам вибрати, де його зберегти, і використовувати різні налаштування стійкості. Детальніше тут: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/

Крім того, ви можете перетворити зображення в base64, а потім зберегти рядок у localStorage, але це швидко заповнить вашу квоту, якщо у вас багато зображень або високої роздільної здатності.


-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".
Брендон Аубі

Це неправильно, оскільки елемент контексту не має toDataURLфункції: developer.mozilla.org/en-US/docs/Web/API/… . Ви хочете зателефонувати toDataURLна елемент полотна: developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/…
Crashalot
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.