Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
31
rated 0 times [  34] [ 3]  / answers: 1 / hits: 33049  / 8 Years ago, sat, january 21, 2017, 12:00:00

I am building an Ionic2 app. I am trying to convert an image url to a base64 image. I have found this which I am trying to make use of.



I have the following code:



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


and



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,/, );
}


But, it outputs the following:




data:,




I get no errors, but expect a base64 image.



My code must me incorrect. Can anyone please advise how to convert the url to a base64 image?



Thanks



UPDATE



Thank you to the feedback from the guys below, I have followed their advise to wit for the image to load. Now I have the following 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,/, ));
});
});
}


usage:



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

});


This does seem to create a base64 image when I run the console.log.



However, I do get the following error:




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



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



I would have thought the following code would resolve this security issue, but to no avail:



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


More info:



Full error:



: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)

More From » base64

 Answers
86

Image instance fires onload event when the image is fully loaded. With this, another issue comes in which is dealing asynchronous functions. To be able to use what getBase64Image uses, a callback function must be used. Without a callback function, the function returns undefined



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


Adjusted function



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;

}


Usage:



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

[#59261] Thursday, January 19, 2017, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
ammonderekm

Total Points: 247
Total Questions: 105
Total Answers: 98

Location: Tuvalu
Member since Sat, Feb 11, 2023
1 Year ago
;