2016-09-26 6 views
-1

Versuchen, Benutzerbild auf Server zu speichern. Sehr neu, dies zu, so dass ich umsah gerade erst begonnen und ich fand den folgenden Code:JavaScript: Fehler beim Konvertieren von Benutzer inputed Bild zu Base64

function getBase64Image(imgElem) { 

    let canvas = document.createElement('canvas'); 
    canvas.width = imgElem.clientWidth; 
    canvas.height = imgElem.clientHeight; 

    let ctx = canvas.getContext('2d'); 
    ctx.drawImage(imgElem, 0, 0); 

    let dataURL = canvas.toDataURL('image/png'); 
    return dataURL.replace(/^data:image\/(png|jpg);base64,/, ''); 

} 

Ich bin mit dieser Funktion kann ein Benutzer eingegebene Bild auf meinem lokalen Server zu speichern, aber ich bekomme die folgende Fehlermeldung:

factories.js:1 Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'getBase64Image @ factories.js:1SubmitRecipe @ recipe-submission.js:1onclick @ submitrecipe:43

ich packte das Bild mit einem Eingang-Tag, das type Satz file hat. Hier ist mein Code:

HTML

<label>Image</label> 
<span class='err-message' id='image-err'></span></br> 
<input type="file" id='image'> 

JS

function SubmitRecipe() { 

    //sets the recipe object and its keys 
    let recipe = { alias: null, description: null, category: null, instructions: null, image: null }; 

    let img = document.getElementById('image'); 
    recipe.image = JSON.stringify(getBase64Image(img)); 

} 

Ich glaube, das Problem mit der Tatsache zu tun hat, dass das Element image ist ein HTMLInputElement, und dass isn 't was drawImage erwartet. Ich habe nur keine Ahnung, wie ich es lösen soll.

Alle Hilfe ist willkommen.

+0

Haben Sie canvas Element in Ihrem HTML platziert ?? –

+0

Wenn Sie haben Sind Sie sicher, dass diese Funktion beim erfolgreichen Laden des Bildes aufgerufen wurde? Ich meine onload-Ereignis –

+0

@kernallora Ist das nicht was 'Canvas = document.createElement (' canvas '); 'tut? Und der Fehler kommt von 'ctx.drawImage (imgElem, 0, 0);', also glaube ich, dass die Funktion aufgerufen wird. – user5854440

Antwort

1

Sie können dazu das FileReader-Objekt verwenden. Das wirklich nette Ding ist, dass es uns sogar die Daten als Daten-URL geben kann - das bedeutet, dass wir Bilder nicht konvertieren/rekomprimieren. Ein JPG wird nicht durch Speichern als PNG vergrößert, noch verliert ein PNG Details durch Umwandlung in ein JPG. Da wir die Leinwand nicht mehr zum Erstellen der URL verwenden, haben wir keine Kontrolle mehr über den genauen Pantomime-Typ. Als solche können wir eine JPG-, PNG- oder JPEG-Datei haben - das bedeutet nur, |jpeg der Regex hinzuzufügen, damit wir auch Instanzen davon ersetzen.

Sie können auch das Ereignis change der Dateieingabe abhören. Auf diese Weise können Sie die Größe und den Typ der Datei überprüfen, um sicherzustellen, dass sie akzeptabel sind. (Jemand könnte eine 100MB Textdatei wählen Sie die Datei Eingabe mit)

function byId(id){return document.getElementById(id)} 
 
function newEl(tagName){return document.createElement(tagName)} 
 

 
window.addEventListener('load', onDocLoaded, false); 
 
function onDocLoaded(evt) 
 
{ 
 
\t byId('goBtn').addEventListener('click', onBtnClicked, false); 
 
} 
 

 
function onBtnClicked(evt) 
 
{ 
 
\t let imgInput = byId('imageInput'); 
 
\t let chosenFile = imgInput.files[0]; 
 
\t let fr = new FileReader(); 
 
\t fr.onload = function(evt) 
 
\t \t \t \t { 
 
        var img = newEl('img'); 
 
        document.body.appendChild(img); 
 
        img.src = this.result; 
 
     
 
\t \t \t \t \t var dataURL = this.result.replace(/^data:image\/(png|jpg|jpeg);base64,/, ''); 
 
\t \t \t \t \t let recipe = { alias: null, description: null, category: null, instructions: null, image: JSON.stringify(dataURL) }; 
 
\t \t \t \t \t console.log(recipe); 
 
\t \t \t \t }; 
 
\t fr.readAsDataURL(chosenFile); 
 
}
<label>Image</label> 
 
\t <span class='err-message' id='image-err'></span></br> 
 
\t <input type="file" id='imageInput'> 
 
\t <button id='goBtn'>GO</button>

+0

Das funktioniert. Aus Neugier, wie würde ich dieses Bild wieder auf dem DOM anzeigen? I.e. Stellen Sie es als Quelle für ein Bild-Tag ein? – user5854440

+0

Lustigerweise ist das genau das, was Sie tun! Ich habe meine Demo aktualisiert, um eine Vorschau des Bildes anzuzeigen. Beachten Sie, dass ich es mit dem rohen Ergebnis des Filereaders mache, ohne die Zeichenfolge mit dem Regex oder Json-in zu ändern. Die ganze Idee von base64 der Quelle ist, dass es bereits übertragbarer (übersetzbarer) Text ist, wie er ist. Also, yuo kann das Bildattribut Ihres Rezepts einfach auf das base64-Ergebnis setzen und dann 'json.stringify' das ganze, anstatt die Bildquelle und' json zu ändern.Beschreibe es vor dem Speichern in das Bildattribut des Rezeptobjekts. – enhzflep

+0

Ie - 'fr.onload = Funktion (evt) {let Rezept = {alias: null, Beschreibung: null, Kategorie: null, Anweisungen: null, image: this.result}; console.log (Rezept);} ' – enhzflep

0

Die Frage ist nicht Dateipfad durch Eingabe im Chrom passieren bekommen konnte, FireFox, kann IE8 es bekommen, wenn ausgewählte Datei.

Verwandte Themen