Javascript 将 URL 转换为 BASE64 图像

2022-01-13 00:00:00 base64 javascript ionic2

我正在构建一个 Ionic2 应用程序.我正在尝试将图像 url 转换为 base64 图像.我找到了我正在尝试使用的 this.

我有以下代码:

var imgUrl = 'https://www.google.de/images/srpr/logo11w.png';让 base64image = this.getBase64Image(imgUrl);控制台.log(base64image);

public getBase64Image(imgUrl) {var img = new Image();img.src = imgUrl;img.setAttribute('crossOrigin', '匿名');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,/, "");}

但是,它会输出以下内容:

<块引用>

数据:,

我没有收到任何错误,但需要的是 base64 图像.

我的代码一定不正确.谁能告诉我如何将 url 转换为 base64 图像?

谢谢

更新

感谢以下人员的反馈,我已按照他们的建议来加载图像.现在我有以下代码:

public getBase64Image(imgUrl): Promise{return new Promise<string>(resolve => {var img = new Image();img.src = imgUrl;img.setAttribute('crossOrigin', '匿名');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);解析(dataURL.replace(/^data:image/(png|jpg);base64,/, ""));});});}

用法:

 let promise64: Promise;= this.getBase64Image(personModel.avatar);promise64.then((数据) => {personModel.avatar64 = 数据;});

当我运行 console.log 时,这似乎确实创建了一个 base64 图像.

但是,我确实收到以下错误:

<块引用>

错误:无法在HTMLCanvasElement"上执行toDataURL":可能无法导出受污染的画布.在 HTMLImageElement.img.onload (utilityService.ts:80)

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

我原以为以下代码可以解决此安全问题,但无济于事:

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

更多信息:

完全错误:

 <代码>:8100/iVBORw0KGgoAAAANSUhEUgAAAbgAAAG5CAYAAAD8liEWAAAgAElEQVR4Xty9B3NkR5Ksm ... bNkFj80enI0JnJ80 + gTsx2sbrX9zhp7k1oOOPZ5K7Oh/AvN0hP6tzZ6QAAAAAElFTkSuQmCC:1 GET HTTP://本地主机:8100/iVBORw0KGgoAAAANSUhEUgAAAbgAAAG5CAYAAAD8liEWAAAgAElEQ ... t3bNkFj80enI0JnJ80 + gTsx2sbrX9zhp7k1oOOPZ5K7Oh/AvN0hP6tzZ6QAAAAAElFTkSuQmCC净:: ERR_EMPTY_RESPONSEpolyfills.js:3 POST http://localhost:8080/jbosswildfly-1.0/person/updatetime 400(错误请求)e@polyfills.js:3t.scheduleTask@polyfills.js:3e.scheduleMacroTask@polyfills.js:3(匿名)@ polyfills.js:3发送@VM9549:3(匿名)@xhr_backend.js:117Observable.subscribe@Observable.js:45MapOperator.call@map.js:54Observable.subscribe@Observable.js:42(匿名)@personService.ts:141t@polyfills.js:3PersonService.updateTimeStamps@personService.ts:140(匿名)@searchjobsParent.ts:109t.invoke@polyfills.js:3onInvoke@ng_zone.js:236t.invoke@polyfills.js:3onInvoke@ng_zone.js:236t.invoke@polyfills.js:3e.run@polyfills.js:3(匿名)@ polyfills.js:3t.invokeTask@polyfills.js:3onInvokeTask@ng_zone.js:227t.invokeTask@polyfills.js:3onInvokeTask@ng_zone.js:227t.invokeTask@polyfills.js:3e.runTask@polyfills.js:3我@polyfills.js:3polyfills.js:3 GET http://localhost:8080/jbosswildfly-1.0/person/list/favouritejob/null/0/400(错误请求)例外:无法在HTMLCanvasElement"上执行toDataURL":可能无法导出受污染的画布.ErrorHandler.handleError@error_handler.js:47IonicErrorHandler.handleError @ ionic-error-handler.js:56下一个@application_ref.js:272schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub@Subscriber.js:223SafeSubscriber.next@Subscriber.js:172订阅者._next @订阅者.js:125订阅者.next@订阅者.js:89Subject.next@Subject.js:55EventEmitter.emit@async.js:74NgZone.triggerError @ ng_zone.js:278onHandleError @ ng_zone.js:257t.handleError @ polyfills.js:3e.runTask@polyfills.js:3调用@polyfills.js:3error_handler.js:52 原始堆栈跟踪:ErrorHandler.handleError@error_handler.js:52IonicErrorHandler.handleError @ ionic-error-handler.js:56下一个@application_ref.js:272schedulerFn @ async.js:82SafeSubscriber.__tryOrUnsub@Subscriber.js:223SafeSubscriber.next@Subscriber.js:172订阅者._next @订阅者.js:125订阅者.next@订阅者.js:89Subject.next@Subject.js:55EventEmitter.emit@async.js:74NgZone.triggerError @ ng_zone.js:278onHandleError @ ng_zone.js:257t.handleError @ polyfills.js:3e.runTask@polyfills.js:3调用@polyfills.js:3error_handler.js:53 错误:无法在HTMLCanvasElement"上执行toDataURL":可能无法导出受污染的画布.在 HTMLImageElement.img.onload (utilityService.ts:82)在 HTMLImageElement.n [as _onload] (polyfills.js:2)在 t.invokeTask (polyfills.js:3)在 Object.onInvokeTask (ng_zone.js:227)在 t.invokeTask (polyfills.js:3)在 e.runTask (polyfills.js:3)在 HTMLImageElement.invoke (polyfills.js:3)

解决方案

当图像完全加载时,图像实例会触发 onload 事件.有了这个,另一个问题是处理异步函数.为了能够使用 getBase64Image 使用的内容,必须使用回调函数.没有回调函数,函数返回 undefined

让 base64image = this.getBase64Image(imgUrl);控制台.log(base64image);//不明确的

调整功能

public getBase64Image(imgUrl, callback) {var img = new Image();//onload 当图像完全加载时触发,并且具有宽度和高度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"),dataURL = dataURL.replace(/^data:image/(png|jpg);base64,/, "");回调(数据URL);//base64 字符串};//设置属性和srcimg.setAttribute('crossOrigin', '匿名');//img.src = imgUrl;}

用法:

this.getBase64Image(imgUrl, function(base64image){控制台.log(base64image);});

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)

解决方案

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

相关文章