2016-04-27 13 views
0

So Im eine App mit Elektronen zu bauen versucht, das Programm ist ziemlich einfach herunterladen, sollte der Benutzer ein paar Bilder hochladen, sie eine Taste drücken, ziehe ich sie in ein <canvas> Element, und sie sollten sein Lage, es zu downloaden, ist das Problem, dass im mit, dass, wenn ich versuche, eine herunterladbare Taste zu machen, wird ein Sicherheitsfehler geworfen, ich tat etwas Forschung und finden sie heraus, dass es eine Funktion von HTML5 ist, ist die Meinung ist, dass ich nicht hinzufügen die crossOrigin = 'Anonymous', weil der Benutzer das Bild von seinem eigenen Computer laden wird, so ist meine Frage ...Kann nicht Leinwand Inhalt

a) - gibt es eine Möglichkeit, "das System zu betrügen" und in der Lage sein, die Inhalt der Leinwand ?,

b) - Wenn (a) nicht möglich ist ... gibt es eine Alternative, die ähnlich wie ein Canvas-Element funktionieren könnte?

Ich benutze bereits FileReader(), um das Bild zu erhalten, das der Benutzer ausgewählt hat, und ich zeichne das bereits in den Canvas, und es sieht gut aus, das Problem, das ich habe, ist, dass ich den Inhalt nicht herunterladen kann das habe ich für diesen Sicherheitsfehler erstellt. Die .toDataURL kann nicht aufgerufen werden, da dies der Fehler ist.

Der Code, um die Bilder von den Eingängen zu lesen:

function handleBox1(evt) { 
    var files = evt.target.files; // FileList object 

    for (var i = 0, f; f = files[i]; i++) { 
     // Only process image files. 
     if (!f.type.match('image.*')) { 
     continue; 
     } 
     var reader = new FileReader(); 

     reader.onload = (function(theFile) { 
     return function(e) { 

      $('#imgBox1').attr("src",e.target.result);    

     }; 
     })(f); 
     // Read in the image file as a data URL. 
     reader.readAsDataURL(f); 
    } 
} 

dies ist eine einfache Funktion, um zu sehen, ob ich die URL von der Leinwand bekommen konnte:

descargar = function(){ 
    var w=window.open('about:blank','image from canvas'); 
    w.document.write("<img src='"+ totem.toDataURL("image/png")+ "' alt='from canvas'/>"); 
} 
+0

können Sie Ihren Code und Fehler posten? Ein Ja-Kreuz-Ursprung bezieht sich überhaupt nicht auf die Benutzer-Uploads. Es wird aufgrund von Websites Dritter oder Links verursacht. –

+0

"... das System betrügen": Nein, die Sicherheitsanforderungen erfüllen: Ja. Wenn der Benutzer über einen modernen Browser verfügt, können Sie mithilfe von FileReader lokale Bilder abrufen, ohne Sicherheitseinschränkungen auszulösen. Der Schlüssel ist, dass der Benutzer explizit die gewünschte Datei auswählen muss und dadurch explizit die Verantwortung für das Hochladen eines domänenübergreifenden Bildes übernehmen muss. – markE

+0

@markE Die verknüpfte Frage erscheint nicht, um mehrere Bilder auf ein einziges '' Element zu zeichnen? – guest271314

Antwort

1

soll der Benutzer Lade ein paar Bilder hoch, ich zeichne sie in ein Element und sie sollten es herunterladen können

Sie können for Schleife verwenden eine IIFE enthält files Objekt aus input type="file" Element zu verarbeiten, new Image, onload Falle <img> Element, URL.createObjectURL(), Array.prototype.sort()width größten der beiden hochgeladenen Bilder zu bestimmen; Promise.all(), Array.prototype.forEach() zu verarbeiten img Elemente; canvas.toBlob() polyfill, um eine objectURL von image zu erstellen; <a> Element download Attribut auf objectURL einzelnes Bild aus zwei Bildern erstellt darstellt; widerrufen objectURL bei click von a Element nach dem Download des Bildes abgeschlossen ist.

// if (!HTMLCanvasElement.prototype.toBlob) { 
 
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { 
 
    value: function(callback, type, quality) { 
 

 
    var binStr = atob(this.toDataURL(type, quality).split(',')[1]), 
 
     len = binStr.length, 
 
     arr = new Uint8Array(len); 
 

 
    for (var i = 0; i < len; i++) { 
 
     arr[i] = binStr.charCodeAt(i); 
 
    } 
 

 
    callback(new Blob([arr], { 
 
     type: type || 'image/png' 
 
    })); 
 
    } 
 
}); 
 
//} 
 

 
var input = document.querySelector("input"); 
 
var canvas = document.querySelector("canvas"); 
 
var a = document.querySelector("a"); 
 
var ctx = canvas.getContext("2d"); 
 
var urls = []; 
 

 
input.onchange = function(e) { 
 
    var images = []; 
 

 
    for (var i = 0; i < e.target.files.length; i++) { 
 
    (function(j) { 
 
     // var reader = new FileReader(); 
 
     // reader.onload = function(event) { 
 
     var img = new Image; 
 
     img.onload = function() { 
 
      images.push(Promise.resolve(this)); 
 
      if (images.length === e.target.files.length) { 
 
      Promise.all(images) 
 
       .then(function(data) { 
 
       data.sort(function(a, b) { 
 
        return a.naturalHeight < b.naturalHeight; 
 
       }) 
 
       data.forEach(function(el, index) { 
 
        if (index === 0) { 
 
        canvas.width = el.naturalWidth; 
 
        canvas.height = el.naturalHeight 
 
            + data[index + 1].naturalHeight; 
 
        ctx.drawImage(el, 0, 0); 
 
        } else { 
 
        ctx.drawImage(el, 0, canvas.height - el.naturalHeight); 
 
        } 
 

 
       }); 
 
       canvas.toBlob(function(blob) { 
 
        var url = URL.createObjectURL(blob); 
 
        console.log(blob); 
 
        a.href = url; 
 
        a.style.display = "block"; 
 
        urls.push(url); 
 
       }); 
 
       }) 
 
      } 
 
     } 
 
     img.src = URL.createObjectURL(e.target.files[j]); 
 
     // } 
 
     // reader.readAsDataURL(e.target.files[j]); 
 
    }(i)) 
 
    } 
 
} 
 

 
a.onclick = function() { 
 
    setTimeout(function() { 
 
    urls.forEach(function(obj) { 
 
     URL.revokeObjectURL(obj) 
 
    }) 
 
    }) 
 
}
<a download="" href="" style="display:none">download</a> 
 
<input type="file" accept="image/*" multiple /> 
 
<br> 
 
<canvas></canvas>

+1

Ihr Code schlägt in IE und Edge fehl, da das Attribut 'download' in diesen Browsern nicht unterstützt wird. Aber ein Grund dafür, FileReader zu verwenden, um Cross-Origin-Restriktionen zu erfüllen. – markE

+0

@markE Siehe http://stackoverflow.com/questions/38711803/how-to-download-a-file-without-a-e-element-mit-download-attribute-oder-a-se – guest271314

+0

Eigentlich warum das über Komplikation von FileReader hier? Sie verlassen sich bereits auf die Existenz von URL, also verwenden Sie es vollständig, es wird eine Ebene der Verschachtelung entfernen. – Kaiido

Verwandte Themen