Canvas.toDataURL () ile Tuvali Resim Olarak Kaydetme


141

Şu anda bir HTML5 web uygulaması / Phonegap yerel uygulaması oluşturuyorum ve tuvalimi bir görüntü olarak nasıl kaydedeceğimizi anlayamıyorum canvas.toDataURL(). Biri bana yardım edebilir mi?

İşte kod, sorun ne?

// Tuvalime "canvasSignature" adı verildi

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
OP'nin sorusu yanıtlanmadı. Bunun Phonegap / iPad için olduğunu açıkça söyledi. Verilen cevaplar bir masaüstü tarayıcısına kaydetmek içindir.
tshm001

1
Telefon aralığı hakkında emin değilim, ancak bunu diğer ucunda JavaScript kullanarak yerel iOS'ta sıfırdan yaptım, verileri ile yakaladım .toDataURL(), sonra tarayıcıyı işaret etmek için window.location komutunu kullanıyorum appname://[data url]. Uygulama sonunda, UIWebView, bir sayfa yüklemesi gerekip gerekmediğini belirten bir temsilci yöntemine sahiptir. Geldiğinde dinler appname://ve bozar, sayfa yükünü reddeder ve yerel bir dizede veri URL'sini yakalarım ... gerçek iOS / Objective C kodu hakkında ne kadar bilginiz var?
Doug

Yanıtlar:


121

İşte bazı kod. hatasız.

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 standart modları hariç: "Bu web sayfasındaki bazı içerik veya dosyalar yüklemediğiniz bir program gerektiriyor." Internet Explorer 8 ve üstü yalnızca CSS, <link> ve <img> içindeki görüntüler için veri URI'lerini destekler: developer.mozilla.org/en-US/docs/data_URIs
Cees Timmerman

45
iyi çalışıyor. indirilen dosyanın adını nasıl değiştirebilirim? sadece "indir" ve uzatma olmadan geliyor. Teşekkürler!
Leabdalla

1
Chrome'da bu tarayıcıyı kilitler. Görüntüyü bir görüntü etiketinde görüntülersem işe yarar, ancak sağ tıklama menüsü gri renktedir - bu yüzden görüntüyü hala kaydedemiyorum.
Kokodoko

Bu harika çalışıyor ... Ama Android'de (Galaxy S3'te varsayılan tarayıcı) sadece görüntüyü indirmiyor, ancak sonsuza kadar "İndiriliyor ..." mesajını alıyorum.
Habrashat

Bazıları bu bağlantıyı görmeme yardımcı olabilecek bir sorunum var: stackoverflow.com/questions/25131763/…
Ramesh S

36

Bu çözüm, indirilen dosyanın adını değiştirmenize olanak tanır:

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

Bunun için teşekkür ederim, bana çok yardımcı oldu!
Mike Moon

22

İndirme istemi için canvas2image kullanabilirsiniz .

Aynı sorunu yaşadım, hem görüntüyü sayfaya ekleyen hem de tarayıcıyı indirmeye zorlayan basit bir örnek:

<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
Sadece denedim, Chrome'da adı veya uzantısı olmayan bir dosyayı kaydedecek.
malber

Burada belirtildiği gibi nihilogic.dk/labs/canvas2image dosya adını ayarlamak mümkün görünmüyor: "Bir şekilde bir dosya adı verilere eklenebilseydi gerçekten düzgün olurdu, ama bunu yapmanın bir yolu bulamadım. Şimdilik dosya adını kendiniz belirtmelisiniz. "
SColvin


9

Bunu deneyebilirsiniz; sahte bir HTML bağlantısı oluşturun ve resmi oradan indirin ...

// 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
Link öğesinin oluşturulması da dahil olmak üzere her şeyin JS'de yapıldığını seviyorum. Otomasyon amaçları için harika çalışıyor
Jeromy Adofo

Mükemmel çözüm
Hidayt Rahman

8

Bunu yapan küçük bir kütüphane oluşturdum (diğer bazı kullanışlı dönüşümlerle birlikte). Buna reimg deniyor ve kullanımı gerçekten basit.

ReImg.fromCanvas(yourCanvasElement).toPng()


Serin kütüphane. Teşekkürler. Yine de örnek belgelerde küçük bir sorun var. Dikkatinize sunmak için Github'da bir konu açtım.
15:16

7

Bu iş benim için: (Sadece 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>

Belki de kodunuzun herhangi bir yorum yapmadan yapıştırmak yerine soruyu cevaplayan kısmını açıklayabilirsiniz?
Gediminas Masaitis

6

1000Bugy'nin cevabına benzer, ancak daha basittir, çünkü anında bir çapa yapmanız ve bir tıklama olayını manuel olarak (ayrıca bir IE düzeltmesi) göndermeniz gerekmez.

İndirme düğmenizi bir tutturucu yaparsanız, varsayılan tutturma işlevi çalışmadan hemen önce üzerine ekleyebilirsiniz. Böylece onAnchorClickçapa href'i canvas base64 görüntüsüne ve çapa indirme özniteliğini resminizi adlandırmak istediğiniz şeye ayarlayabilirsiniz.

Bu, (geçerli) IE'de çalışmaz, çünkü indirme özniteliğini uygulamaz ve veri urisinin indirilmesini önler. Ancak bu, window.navigator.msSaveBlobbunun yerine kullanılarak düzeltilebilir .

Sizin çapa tıklama olay işleyicisi olarak takip (burada olacak Yani anchor, canvasve fileNamekapsam aramaları şunlardır):

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

İşte bir keman


1

Bunun yerine imageElement.src = myImage;kullanmalısınwindow.location = myImage;

Ve bundan sonra bile tarayıcı görüntünün kendisini gösterecektir. Görüntüyü indirmek için sağ tıklayıp "Bağlantıyı Kaydet" seçeneğini kullanabilirsiniz.

Daha fazla bilgi için bu bağlantıyı kontrol edin .


Vay canına, teşekkürler, bu gerçekten çok yardımcı oldu :) Ama bir pop-up kaydetme kutusu nasıl alırsınız, böylece birisi belirli bir hedefe (Android görüntüleri klasörü gibi) kaydedebilir?
Wardenclyffe

Belirli tarayıcıya bağlıdır. Android tarayıcı genellikle dosyaları doğrudan belirli bir klasöre indirir.
Hakan Serce

Chrome'da bu çalışır, ancak sağ tıklama menüsü gri görünür. Görüntüyü tarayıcıdan 'sürüklemeye' çalışırken Chrome kilitleniyor.
Kokodoko

groups.google.com/a/chromium.org/forum/#!topic/blink-dev/… Bunun gibi veri URL'lerinin açılması engellenecek gibi görünüyor.
KeyOfJ

0

Cordova'da çalışırken bir görüntüyü indirmek için daha önce belirtilen yöntemleri kullanamazsınız. Cordova Dosya Eklentisini kullanmanız gerekecektir . Bu, nereye kaydedeceğinizi seçmenize ve farklı kalıcılık ayarlarından yararlanmanıza olanak tanır. Ayrıntılar burada: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/

Alternatif olarak, görüntüyü base64'e dönüştürebilir ve ardından dizeyi localStorage'da saklayabilirsiniz, ancak çok sayıda resminiz veya yüksek çözünürlüklü varsa kotanızı hızla dolduracaktır.


-9

@Wardenclyffe ve @SColvin, ikiniz de tuvalin içeriğini kullanarak tuvali kullanarak görüntüyü kaydetmeye çalışıyorsunuz. her ikisi de ctx.toDataURL (); Bunu dene:

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>

Ayrıca aşağıdaki bağlantılara başvurabilirsiniz:

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


Yakalanmayan TypeError: Nesne # <CanvasRenderingContext2D> 'toDataURL' yöntemine sahip değil.
Brandon Aubie

Bağlam öğesinin bir toDataURLişlevi olmadığından bu yanlıştır : developer.mozilla.org/en-US/docs/Web/API/… . toDataURLTuval öğesini aramak istiyorsunuz : developer.mozilla.org/tr-TR/docs/Web/API/HTMLCanvasElement/…
Crashalot
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.