2017-01-21 6 views
2

Ich baue eine Ionic2 App. Ich versuche, eine Bild-URL in ein Base64-Bild zu konvertieren. Ich habe this gefunden, die ich versuche zu verwenden.Javascript Konvertiere eine URL in ein BASE64 Bild

Ich habe den folgenden Code:

var imgUrl = 'https://www.google.de/images/srpr/logo11w.png'; 
let base64image = this.getBase64Image(imgUrl); 
console.log(base64image); 

und

public getBase64Image(imgUrl) { 
    var img = new Image(); 
    img.src = imgUrl; 
    img.setAttribute('crossOrigin', 'anonymous'); 
    var canvas = document.createElement("canvas"); 
    canvas.width = img.width; 
    canvas.height = img.height; 
    var ctx = canvas.getContext("2d"); 
    ctx.drawImage(img, 0, 0); 
    var dataURL = canvas.toDataURL("image/png"); 
    return dataURL.replace(/^data:image\/(png|jpg);base64,/, ""); 
} 

Aber es gibt die folgenden:

data:,

ich keine Fehler, aber ein base64 Bild erwarten.

Mein Code muss mich inkorrekt sein. Kann jemand bitte beraten, wie man die URL in ein base64 Bild umwandelt?

Dank

UPDATE

Sie von den Jungs unten auf das Feedback danken, ich habe ihr Rat an Witz gefolgt das Bild laden zu. Jetzt habe ich den folgenden Code:

public getBase64Image(imgUrl): Promise<string> { 
    return new Promise<string>(resolve => { 
     var img = new Image(); 
     img.src = imgUrl; 
     img.setAttribute('crossOrigin', 'anonymous'); 
     img.onload = (() => { 
      var canvas = document.createElement("canvas"); 
      canvas.width = img.width; 
      canvas.height = img.height; 
      var ctx = canvas.getContext("2d"); 
      ctx.drawImage(img, 0, 0); 
      var dataURL = canvas.toDataURL("image/png"); 
      //console.log('UgetBase64Image.dataURL ', dataURL); 
      resolve(dataURL.replace(/^data:image\/(png|jpg);base64,/, "")); 
     }); 
    }); 
} 

Nutzung:

       let promise64: Promise<string> = this.getBase64Image(personModel.avatar); 
           promise64.then((data) => { 
            personModel.avatar64 = data; 

           }); 

Dies scheint ein base64 Bild zu erzeugen, wenn ich die console.log laufen.

Aber ich erhalte den folgenden Fehler:

Error: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 
    at HTMLImageElement.img.onload (utilityService.ts:80) 

Linie 80: var dataURL = canvas.toDataURL("image/png");

ich den folgenden Code, um dieses Sicherheitsproblem würde lösen hätte gedacht, aber ohne Erfolg:

img.setAttribute('crossOrigin', 'anonymous'); 

Weitere Informationen:

Vollständiger Fehler:

:8100/iVBORw0KGgoAAAANSUhEUgAAAbgAAAG5CAYAAAD8liEWAAAgAElEQVR4Xty9B3NkR5Ksm…bNkFj80enI0JnJ80+gTsx2sbrX9zhp7k1oOOPZ5K7Oh/AvN0hP6tzZ6QAAAAAElFTkSuQmCC:1 GET http://localhost:8100/iVBORw0KGgoAAAANSUhEUgAAAbgAAAG5CAYAAAD8liEWAAAgAElEQ…t3bNkFj80enI0JnJ80+gTsx2sbrX9zhp7k1oOOPZ5K7Oh/AvN0hP6tzZ6QAAAAAElFTkSuQmCC net::ERR_EMPTY_RESPONSE 
polyfills.js:3 POST http://localhost:8080/jbosswildfly-1.0/person/updatetime 400 (Bad Request) 
e @ polyfills.js:3 
t.scheduleTask @ polyfills.js:3 
e.scheduleMacroTask @ polyfills.js:3 
(anonymous) @ polyfills.js:3 
send @ VM9549:3 
(anonymous) @ xhr_backend.js:117 
Observable.subscribe @ Observable.js:45 
MapOperator.call @ map.js:54 
Observable.subscribe @ Observable.js:42 
(anonymous) @ personService.ts:141 
t @ polyfills.js:3 
PersonService.updateTimeStamps @ personService.ts:140 
(anonymous) @ searchjobsParent.ts:109 
t.invoke @ polyfills.js:3 
onInvoke @ ng_zone.js:236 
t.invoke @ polyfills.js:3 
onInvoke @ ng_zone.js:236 
t.invoke @ polyfills.js:3 
e.run @ polyfills.js:3 
(anonymous) @ polyfills.js:3 
t.invokeTask @ polyfills.js:3 
onInvokeTask @ ng_zone.js:227 
t.invokeTask @ polyfills.js:3 
onInvokeTask @ ng_zone.js:227 
t.invokeTask @ polyfills.js:3 
e.runTask @ polyfills.js:3 
i @ polyfills.js:3 
polyfills.js:3 GET http://localhost:8080/jbosswildfly-1.0/person/list/favouritejob/null/0/ 400 (Bad Request) 

EXCEPTION: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 
ErrorHandler.handleError @ error_handler.js:47 
IonicErrorHandler.handleError @ ionic-error-handler.js:56 
next @ application_ref.js:272 
schedulerFn @ async.js:82 
SafeSubscriber.__tryOrUnsub @ Subscriber.js:223 
SafeSubscriber.next @ Subscriber.js:172 
Subscriber._next @ Subscriber.js:125 
Subscriber.next @ Subscriber.js:89 
Subject.next @ Subject.js:55 
EventEmitter.emit @ async.js:74 
NgZone.triggerError @ ng_zone.js:278 
onHandleError @ ng_zone.js:257 
t.handleError @ polyfills.js:3 
e.runTask @ polyfills.js:3 
invoke @ polyfills.js:3 
error_handler.js:52 ORIGINAL STACKTRACE: 
ErrorHandler.handleError @ error_handler.js:52 
IonicErrorHandler.handleError @ ionic-error-handler.js:56 
next @ application_ref.js:272 
schedulerFn @ async.js:82 
SafeSubscriber.__tryOrUnsub @ Subscriber.js:223 
SafeSubscriber.next @ Subscriber.js:172 
Subscriber._next @ Subscriber.js:125 
Subscriber.next @ Subscriber.js:89 
Subject.next @ Subject.js:55 
EventEmitter.emit @ async.js:74 
NgZone.triggerError @ ng_zone.js:278 
onHandleError @ ng_zone.js:257 
t.handleError @ polyfills.js:3 
e.runTask @ polyfills.js:3 
invoke @ polyfills.js:3 
error_handler.js:53 Error: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 
    at HTMLImageElement.img.onload (utilityService.ts:82) 
    at HTMLImageElement.n [as _onload] (polyfills.js:2) 
    at t.invokeTask (polyfills.js:3) 
    at Object.onInvokeTask (ng_zone.js:227) 
    at t.invokeTask (polyfills.js:3) 
    at e.runTask (polyfills.js:3) 
    at HTMLImageElement.invoke (polyfills.js:3) 
+0

Warten, bis das Bild mit 'img.onload' –

+0

Dank Adam, zu laden, zu welchem ​​Punkt muss ich das tun? Bevor ich die Leinwand erstelle? – Richard

+0

Wie lautet die URL des Bildes, an dem der Fehler aufgetreten ist? –

Antwort

1

Bildinstanz wird ausgelöst onload Ereignis, wenn das Bild vollständig geladen ist. Damit kommt ein weiteres Problem hinzu, das asynchrone Funktionen behandelt. Um verwenden zu können, was getBase64Image verwendet, muss eine Callback-Funktion verwendet werden. Ohne eine Callback-Funktion, gibt die Funktion undefined

let base64image = this.getBase64Image(imgUrl); 
console.log(base64image); // undefined 

Adjusted Funktion

public getBase64Image(imgUrl, callback) { 

    var img = new Image(); 

    // onload fires when the image is fully loadded, and has width and height 

    img.onload = function(){ 

     var canvas = document.createElement("canvas"); 
     canvas.width = img.width; 
     canvas.height = img.height; 
     var ctx = canvas.getContext("2d"); 
     ctx.drawImage(img, 0, 0); 
     var dataURL = canvas.toDataURL("image/png"), 
      dataURL = dataURL.replace(/^data:image\/(png|jpg);base64,/, ""); 

     callback(dataURL); // the base64 string 

    }; 

    // set attributes and src 
    img.setAttribute('crossOrigin', 'anonymous'); // 
    img.src = imgUrl; 

} 

Verbrauch:

this.getBase64Image(imgUrl, function(base64image){ 
    console.log(base64image); 
}); 
+0

Danke, ich werde es versuchen. – Richard

1

Um können Bilder von einem anderen Ursprung (Server) auf einer Leinwand verwenden, um das Bild muss mit CORS-Headern geliefert werden. This page on MDN erklärt es.

var imgUrl = 'https://www.google.de/images/srpr/logo11w.png'; 
 
var imgUrl = 'https://dl.dropboxusercontent.com/u/139992952/coffee.png'; 
 

 

 
let base64image = getBase64Image(imgUrl).then(function(base64image) { 
 
    console.log(base64image); 
 
}, function(reason) { 
 
    console.log(reason); // Error! 
 
}); 
 

 

 
function getBase64Image(imgUrl) { 
 
    return new Promise(
 
    function(resolve, reject) { 
 

 
     var img = new Image(); 
 
     img.src = imgUrl; 
 
     img.setAttribute('crossOrigin', 'anonymous'); 
 

 
     img.onload = function() { 
 
     var canvas = document.createElement("canvas"); 
 
     canvas.width = img.width; 
 
     canvas.height = img.height; 
 
     var ctx = canvas.getContext("2d"); 
 
     ctx.drawImage(img, 0, 0); 
 
     var dataURL = canvas.toDataURL("image/png"); 
 
     resolve(dataURL.replace(/^data:image\/(png|jpg);base64,/, "")); 
 
     } 
 
     img.onerror = function() { 
 
     reject("The image could not be loaded."); 
 
     } 
 

 
    }); 
 

 
}

+0

Danke. Ich habe versucht, aber jetzt bekomme ich einen Sicherheitsfehler (siehe UPDATE oben). – Richard

Verwandte Themen