Làm cách nào để lưu Canvas dưới dạng hình ảnh với canvas.toDataURL ()?


141

Tôi hiện đang xây dựng một ứng dụng web HTML5 / ứng dụng gốc Phonegap và dường như tôi không thể tìm ra cách lưu canvas của mình dưới dạng hình ảnh canvas.toDataURL(). có ai giúp tôi ra ngoài không?

Đây là mã, có gì sai với nó?

// Canvas của tôi được đặt tên là "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
Câu hỏi của OP chưa được trả lời. Ông nói rõ ràng đây là dành cho Phonegap / iPad. Các câu trả lời được đưa ra là để lưu trên trình duyệt máy tính để bàn.
tshm001

1
Không chắc chắn về phonegap, nhưng tôi đã thực hiện điều này từ đầu trong iOS gốc bằng cách sử dụng JavaScript ở đầu bên kia, tôi chụp dữ liệu với .toDataURL(), sau đó sử dụng window.location để trỏ trình duyệt tới appname://[data url]. Ở cuối ứng dụng, UIWebView có một phương thức ủy nhiệm cho biết có nên tải trang hay không. Tôi lắng nghe appname://và phân tích nó khi nó đến, từ chối tải trang và nắm bắt url dữ liệu trong một chuỗi gốc ... bạn quen thuộc với mã C / iOS / Objective thực tế như thế nào?
Doug

Câu trả lời:


121

Đây là một số mã. không có lỗi

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
Ngoại trừ trong chế độ tiêu chuẩn IE9: "Một số nội dung hoặc tệp trên trang web này yêu cầu chương trình mà bạn chưa cài đặt." Internet Explorer 8 trở lên chỉ hỗ trợ URI dữ liệu cho hình ảnh trong CSS, <link> và <img>: developer.mozilla.org/en-US/docs/data_URIs
Cees Timmerman

45
hoạt động tốt Làm cách nào để thay đổi tên của tệp đã tải xuống? nó chỉ đến "tải về" và không có phần mở rộng. cảm ơn!
Leabdalla

1
Trong Chrome này bị sập trình duyệt. Nếu tôi hiển thị hình ảnh trong thẻ hình ảnh, nó sẽ hoạt động nhưng menu chuột phải bị mờ đi - vì vậy tôi vẫn không thể lưu hình ảnh.
Kokodoko

Điều này hoạt động rất tốt ... Nhưng trong Android (Trình duyệt mặc định trong Galaxy S3), nó chỉ không tải xuống hình ảnh, nhưng tôi nhận được thông báo "Đang tải xuống ...".
Habrashat

Tôi đã lưu vấn đề mà ai đó có thể giúp tôi xem liên kết này: stackoverflow.com/questions/25131763/iêu
Ramesh S

36

Giải pháp này cho phép bạn thay đổi tên của tệp đã tải xuống:

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

Cảm ơn bạn vì điều này, nó đã giúp tôi rất nhiều!
Mike Moon

21

Bạn có thể sử dụng canvas2image để nhắc tải xuống.

Tôi có cùng một vấn đề, đây là một ví dụ đơn giản, cả hai đều thêm hình ảnh vào trang và buộc trình duyệt tải xuống:

<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
Chỉ cần dùng thử, nó sẽ lưu một tệp không có tên cũng như phần mở rộng trong Chrome.
malber

như đã đề cập ở đây nihilogic.dk/labs/canvas2image, việc đặt tên tệp dường như không thể thực hiện được: "Sẽ rất gọn gàng nếu bằng cách nào đó một tên tệp có thể được gắn vào dữ liệu, nhưng tôi không tìm thấy cách nào để làm điều đó. Hiện tại, bạn phải tự xác định tên tệp. "
SColvin

1
Liên kết bạn đã đăng bị hỏng
Oliver Nybroe

9

Bạn có thể thử điều này; tạo một neo HTML giả và tải xuống hình ảnh từ đó như ...

// 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
Tôi thích thực tế là mọi thứ đã được thực hiện trong JS, bao gồm cả việc tạo phần tử liên kết. Nó hoạt động tuyệt vời cho mục đích tự động hóa
Jeromy Adofo

Giải pháp hoàn hảo
Hidayt Rahman

8

Tôi đã tạo một thư viện nhỏ thực hiện việc này (cùng với một số chuyển đổi tiện dụng khác). Nó được gọi là reimg , và nó thực sự đơn giản để sử dụng.

ReImg.fromCanvas(yourCanvasElement).toPng()


Thư viện mát mẻ. Cảm ơn. Có một vấn đề nhỏ trong tài liệu ví dụ. Tôi đã mở một vấn đề trên Github để khiến bạn chú ý.
jmknoll

7

Công việc này đối với tôi: (Chỉ 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>

Có lẽ bạn có thể giải thích phần mã của mình để trả lời câu hỏi thay vì chỉ dán nó mà không có bất kỳ nhận xét nào?
Gediminas Masa viêm

6

Tương tự như câu trả lời của 1000Bugy nhưng đơn giản hơn vì bạn không phải thực hiện neo một cách nhanh chóng và gửi một sự kiện nhấp bằng tay (cộng với sửa lỗi IE).

Nếu bạn đặt nút tải xuống của mình thành một neo, bạn có thể đánh dấu nó ngay trước khi chức năng neo mặc định được chạy. Vì vậy, onAnchorClickbạn có thể đặt neo href thành hình ảnh canvas base64 và thuộc tính tải xuống neo thành bất cứ điều gì bạn muốn đặt tên cho hình ảnh của mình.

Điều này không hoạt động trong IE (hiện tại) vì nó không triển khai thuộc tính tải xuống và ngăn tải xuống dữ liệu uris. Nhưng điều này có thể được khắc phục bằng cách sử dụng window.navigator.msSaveBlobthay thế.

Vì vậy, trình xử lý sự kiện nhấp chuột neo của bạn sẽ như sau (trong đó anchor, canvasfileNamelà tra cứu phạm vi):

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

Đây là một câu đố


1

Thay vì imageElement.src = myImage;bạn nên sử dụngwindow.location = myImage;

Và thậm chí sau đó trình duyệt sẽ hiển thị hình ảnh chính nó. Bạn có thể nhấp chuột phải và sử dụng "Lưu liên kết" để tải xuống hình ảnh.

Kiểm tra liên kết này để biết thêm thông tin.


Wow, cảm ơn, điều đó thực sự giúp ích rất nhiều :) Nhưng làm thế nào để bạn có được một hộp lưu trữ bật lên, để ai đó có thể lưu vào một đích cụ thể (như thư mục hình ảnh Android của họ)?
Wardenclyffe

Nó phụ thuộc vào trình duyệt cụ thể. Trình duyệt Android thường tải trực tiếp các tệp vào một thư mục cụ thể.
Hakan Serce

Trong Chrome này hoạt động, nhưng menu chuột phải bị mờ đi. Khi cố gắng 'kéo' hình ảnh ra khỏi trình duyệt, Chrome gặp sự cố.
Kokodoko

Groups.google.com/a/chromium.org/forum/#!topic/blink-dev/ mẹo Mở URL dữ liệu như thế này sẽ bị chặn.
KeyOfJ

0

Bạn không thể sử dụng các phương pháp được đề cập trước đây để tải xuống một hình ảnh khi chạy trong Cordova. Bạn sẽ cần sử dụng Plugin Cordova File . Điều này sẽ cho phép bạn chọn nơi lưu nó và tận dụng các cài đặt kiên trì khác nhau. Chi tiết tại đây: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/

Ngoài ra, bạn có thể chuyển đổi hình ảnh thành base64 sau đó lưu trữ chuỗi trong localStorage nhưng điều này sẽ lấp đầy hạn ngạch của bạn khá nhanh nếu bạn có nhiều hình ảnh hoặc độ phân giải cao.


-9

@Wardenclyffe và @SColvin, cả hai bạn đang cố lưu hình ảnh bằng cách sử dụng canvas, không phải bằng cách sử dụng bối cảnh của canvas. cả hai bạn nên thử ctx.toDataURL (); Thử cái này:

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>

Ngoài ra, bạn có thể tham khảo các liên kết sau:

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

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


Uncaught TypeError: Object # <CanvasRenderingContext2D> không có phương thức 'toDataURL'.
Brandon Aubie

Điều này là sai vì phần tử ngữ cảnh không có toDataURLchức năng: developer.mozilla.org/en-US/docs/Web/API/ . Bạn muốn gọi toDataURLphần tử canvas: developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasEuity/
Kẻ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.