2017-01-21 187 views
2

我正在構建一個Ionic2應用程序。我正在嘗試將圖像url轉換爲base64圖像。我發現this,我正在嘗試使用。Javascript將URL轉換爲BASE64圖像

我有以下代碼:

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

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

但是,它輸出以下:

data:,

我沒有得到任何錯誤,但想到一個base64形象。

我的代碼必須是不正確的。任何人都可以請建議如何將網址轉換爲base64圖像?

感謝

UPDATE

謝謝你從下面的傢伙的反饋,我也跟着他們奉勸機智的圖像加載。現在,我有以下代碼:

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

用法:

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

           }); 

這似乎當我運行的console.log創建一個base64形象。

不過,我得到以下錯誤:

Error: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 
    at 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://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

等待圖像加載使用'img.onload' –

+0

感謝亞當,在什麼時候,我必須這樣做嗎?在創建Canvas之前? – Richard

+0

你得到這個錯誤的圖像的URL是什麼? –

回答

1

圖像實例在圖像完全加載時觸發onload事件。有了這個,另一個問題就是處理異步功能。爲了能夠使用getBase64Image使用的內容,必須使用回調函數。如果沒有一個回調函數,該函數返回undefined

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

調整功能

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; 

} 

用法:

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

謝謝,我會放棄它。 – Richard

1

爲了能在畫布上使用的圖片從另一個起源(服務器),圖像必須與CORS標題一起提供。 This page on MDN解釋它。

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

謝謝。我已經嘗試過,但現在正在收到安全錯誤(請參閱上面的UPDATE)。 – Richard