2017-01-21 2 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 изображение.

Мой код должен быть неправильным. Кто-нибудь может посоветовать, как преобразовать URL-адрес в образ 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; 

           }); 

Это, кажется, создать base64 изображение, когда я бегу console.log.

Однако, я получаю следующее сообщение об ошибке:

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

Я бы подумал, следующий код будет решить эту проблему безопасности, но безрезультатно:

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

Благодаря Адам, в какой момент я должен делать это? Прежде чем создать холст? – 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

Смежные вопросы