Jak zapisać płótno jako obraz za pomocą canvas.toDataURL ()?


141

Obecnie tworzę aplikację internetową HTML5 / natywną aplikację Phonegap i nie wiem, jak zapisać płótno jako obraz canvas.toDataURL(). Czy ktoś może mi pomóc?

Oto kod, co jest z nim nie tak?

// Moje płótno nosiło nazwę „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
Nie udzielono odpowiedzi na pytanie OP. Wyraźnie powiedział, że dotyczy to Phonegap / iPad. Podane odpowiedzi służą do zapisania w przeglądarce na komputerze.
tshm001

1
Nie jestem pewien co do phonegap, ale zrobiłem to od zera w natywnym iOS, używając JavaScript na drugim końcu, przechwytuję dane .toDataURL(), a następnie używam window.location, aby wskazać przeglądarkę appname://[data url]. Na końcu aplikacji UIWebView ma metodę delegata, która mówi, czy powinna załadować stronę. Nasłuchuję appname://i rozbijam, gdy się pojawia, odmawiam ładowania strony i przechwytuję adres URL danych w natywnym ciągu ... jak dobrze znasz kod iOS / Objective C?
Doug

Odpowiedzi:


121

Oto kod. bez żadnego błędu.

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
Z wyjątkiem trybu standardowego IE9: „Niektóre treści lub pliki na tej stronie wymagają programu, którego nie masz zainstalowanego”. Internet Explorer 8 i nowsze obsługują tylko identyfikatory URI danych dla obrazów w CSS, <link> i <img>: developer.mozilla.org/en-US/docs/data_URIs
Cees Timmerman,

45
działa w porządku. jak mogę zmienić nazwę pobranego pliku? nadchodzi po prostu „pobierz” i bez rozszerzenia. dzięki!
Leabdalla

1
W Chrome powoduje to awarię przeglądarki. Jeśli wyświetlam obraz w tagu obrazu, działa, ale menu prawego przycisku myszy jest wyszarzone - więc nadal nie mogę zapisać obrazu.
Kokodoko

To działa świetnie ... Ale w Androidzie (domyślna przeglądarka w Galaxy S3) po prostu nie pobiera obrazu, ale na zawsze pojawia się komunikat „Pobieranie ...”.
Habrashat

Mam problem z zapisem, ktoś może mi pomóc zobaczyć ten link: stackoverflow.com/questions/25131763/…
Ramesh S

36

To rozwiązanie umożliwia zmianę nazwy pobranego pliku:

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

Dziękuję za to, bardzo mi to pomogło!
Mike Moon

22

Możesz użyć canvas2image, aby poprosić o pobranie.

Miałem ten sam problem, oto prosty przykład, który zarówno dodaje obraz do strony, jak i zmusza przeglądarkę do pobrania go:

<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
Właśnie go wypróbowałem, zapisze plik bez nazwy ani rozszerzenia w Chrome.
Malber

jak wspomniano tutaj nihilogic.dk/labs/canvas2image, ustawienie nazwy pliku nie wydaje się możliwe: „Byłoby naprawdę fajnie, gdyby w jakiś sposób można było dołączyć nazwę pliku do danych, ale nie znalazłem sposobu, aby to zrobić. Na razie musisz samodzielnie określić nazwę pliku ”.
SColvin,

1
Link, który opublikowałeś jest uszkodzony
Oliver Nybroe

9

Możesz spróbować tego; utwórz fikcyjną kotwicę HTML i pobierz stamtąd obraz, taki jak ...

// 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
Podoba mi się fakt, że wszystko zostało zrobione w JS, łącznie ze stworzeniem elementu link. Działa świetnie do celów automatyzacji
Jeromy Adofo

Idealne rozwiązanie
Hidayt Rahman

8

Stworzyłem małą bibliotekę, która to robi (wraz z kilkoma innymi przydatnymi konwersjami). Nazywa się reimg i jest naprawdę prosty w użyciu.

ReImg.fromCanvas(yourCanvasElement).toPng()


Fajna biblioteka. Dzięki. Jednak w przykładowej dokumentacji jest mały problem. Otworzyłem numer na Github, aby zwrócić na niego uwagę.
jmknoll

7

To działa dla mnie: (tylko 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>

Może mógłbyś wyjaśnić część swojego kodu, która odpowiada na pytanie, zamiast po prostu wklejać ją bez żadnych komentarzy?
Gediminas Masaitis

6

Podobna do odpowiedzi 1000Bugy, ale prostsza, ponieważ nie musisz tworzyć kotwicy w locie i ręcznie wywoływać zdarzenia kliknięcia (plus poprawka IE).

Jeśli ustawisz przycisk pobierania jako kotwicę, możesz go skradać tuż przed uruchomieniem domyślnej funkcji kotwicy. onAnchorClickMożesz więc ustawić href kotwicy na obraz kanwy base64, a atrybut pobierania kotwicy na cokolwiek chcesz nazwać swój obraz.

Nie działa to w (bieżącej) przeglądarce IE, ponieważ nie implementuje atrybutu pobierania i zapobiega pobieraniu danych uris. Ale można to naprawić, używając window.navigator.msSaveBlobzamiast tego.

Więc kotwica obsługi zdarzenia kliknięcia będzie następująco (gdzie anchor, canvasi fileNamesą wyszukiwań zakres):

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

Oto skrzypce


1

Zamiast tego imageElement.src = myImage;powinieneś użyćwindow.location = myImage;

I nawet po tym przeglądarka wyświetli sam obraz. Możesz kliknąć prawym przyciskiem myszy i użyć „Zapisz łącze”, aby pobrać obraz.

Sprawdź to łącze, aby uzyskać więcej informacji.


Wow, dzięki, to naprawdę bardzo pomogło :) Ale jak uzyskać wyskakujące okienko zapisu, aby ktoś mógł zapisać w określonym miejscu (np. W folderze z obrazami na Androida)?
Wardenclyffe

To zależy od konkretnej przeglądarki. Przeglądarka Androida zazwyczaj pobiera pliki bezpośrednio do określonego folderu, na przykład.
Hakan Serce

W Chrome to działa, ale menu prawego przycisku myszy jest wyszarzone. Podczas próby „przeciągnięcia” obrazu z przeglądarki Chrome ulega awarii.
Kokodoko

groups.google.com/a/chromium.org/forum/#!topic/blink-dev/… Wygląda na to, że otwieranie adresu URL danych, takiego jak ten, zostanie zablokowane.
KeyOfJ

0

Nie możesz użyć wyżej wymienionych metod do pobrania obrazu podczas pracy w Cordova. Będziesz musiał użyć wtyczki Cordova File . Umożliwi to wybranie miejsca zapisania i wykorzystanie różnych ustawień trwałości. Szczegóły tutaj: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/

Alternatywnie możesz przekonwertować obraz na base64, a następnie zapisać ciąg w localStorage, ale to dość szybko wypełni twój limit, jeśli masz wiele obrazów lub wysokiej rozdzielczości.


-9

@Wardenclyffe i @SColvin, oboje próbujesz zapisać obraz za pomocą płótna, a nie kontekstu płótna. w obu przypadkach należy spróbować ctx.toDataURL (); Spróbuj tego:

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>

Możesz również skorzystać z poniższych linków:

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: Object # <CanvasRenderingContext2D> nie ma metody „toDataURL”.
Brandon Aubie,

To jest złe, ponieważ element kontekstu nie ma toDataURLfunkcji: developer.mozilla.org/en-US/docs/Web/API/… . Chcesz wywołać toDataURLelement canvas: developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/…
Crashalot
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.