3

I am converting a base64 string into an image, and then passing it to a canvas draw to make it smaller. This is based off a script I found on SO.

function imageToDataUri(img, width, height) {

    // create an off-screen canvas
    var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');

    // set its dimension to target size
    canvas.width = width;
    canvas.height = height;

    // draw source image into the off-screen canvas:
    ctx.drawImage(img, 0, 0, width, height);

    // encode image to data-uri with base64 version of compressed image
    return canvas.toDataURL();
}

I pass in the image element (which is correct before, I've checked), and some of the time this script works correctly and changes the image to the correct size, and other times it generates what I think is a blank image, like this:

iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAEJJREFUaAXt0IEAAAAAw6D5Ux/khVBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYeBwYnQgABzCacsQAAAABJRU5ErkJggg==

I can't find any reproducability - it happens or it doesn't, on the same or different images.

What could be going on? The script seems to work, but only half the time? Everything else is being kept exactly the same.

Edit - this is how the image for the above function is being generated:

                function resizeURI(base64) {

                var img = new Image;

// turns base64 into dataURI
var uri = base64ToDataUri(base64);
img.src = uri;
var resizedURI = resizeImage(img);
// turns dataURI into base64 again
resizedURI = resizedURI.substring(resizedURI.indexOf(",") + 1);
return resizedURI;
                }

function resizeImage(img) {
    var newDataUri = imageToDataUri(img, 50, 50);
    return newDataUri;
}
Steven Matthews
  • 9,705
  • 45
  • 126
  • 232
  • http://stackoverflow.com/questions/11207606/html5-canvas-get-event-when-drawing-is-finished – user3791775 Sep 11 '16 at 01:00
  • Not all base64 formats are the same, they sometimes use different characters. Not sure if that's the problem though. Can you debug this buy attaching the `Image` and the `canvas` to the page and visually inspecting their contents? I'm curious if it fails in the image stage or the canvas stage. – david Sep 11 '16 at 01:27
  • It's definitely failing at the canvas stage. I've taken a look at the image element generated and that always loads correctly. – Steven Matthews Sep 11 '16 at 01:29
  • OH you're not waiting for the image's load event. That might cause it. – david Sep 11 '16 at 01:32
  • Yeah, I think that's what user3791775 was trying to tell me, and I'm in the process of testing that hypothesis out. – Steven Matthews Sep 11 '16 at 01:43
  • Yep, it appears to be based on the onload. If either of you guys wants the honor of putting the answer, I'll accept it, as I am now getting the image data 100% of the time. – Steven Matthews Sep 11 '16 at 01:53
  • Possible duplicate of [CanvasContext2D drawImage() issue \[onload and CORS\]](http://stackoverflow.com/questions/32880641/canvascontext2d-drawimage-issue-onload-and-cors) – Kaiido Sep 11 '16 at 06:54

1 Answers1

0

The reason is because the image is not always loaded when the imageToDataUri is called. you should wait for it to be fully loaded, by adding event listener, and wait for "loaded" event before you call imageToDataUri().

see HTML5 canvas - drawImage not always drawing the image

Micha Kaufman
  • 777
  • 7
  • 11