问题
I am trying to resize an image and get back the base64 string representation using canvas.toDataUrl().
My code is as follows (see below). My issue is that every time when I first initiate it, it returns 'data:,'.
Then when I redo the re-sizing (calling with button), then it works fine and it returns me a nonempty base64 string. What is going on?
function drawAndResizeFunction(images)
var qDraw = $q.defer();
// 1
drawCanvasWrapper().then(function(canvasData){
qDraw.resolve(canvasData)
});
// 2
function drawCanvasWrapper() {
var pResults = images.map(function (imageObj) {
//return drawCanvassIter(imageObj.tempURL); // tempUrl
return resizeIter(imageObj.tempURL).then(function(result){
console.log("resized", result) // *** RETURNS data:, in first attempt
return result;
})
});
return $q.all(pResults);
};
// 3inval
// returns canvasdata
function resizeIter(nativeURL) {
console.log("resizeIter")
var qResize = $q.defer();
var canvas = document.getElementById("resizecanvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = nativeURL;
var newScales = resizeDimensions(img.width, img.height)
var iw =canvas.width =img.width =newScales.iw;
var ih =canvas.height =img.height =newScales.ih;
img.onload = function () {
// --> 4
ctx.drawImage(img, 0, 0, iw, ih);
$timeout(function(){
qResize.resolve(canvas.toDataURL("image/jpeg"));
}, 200)
};
return qResize.promise;
//
//
function resizeDimensions(iw, ih) {
var scaleFactor = 1;
var targetSize = 800;
if (iw > targetSize || ih > targetSize) {
if(iw > ih) {
scaleFactor = targetSize/iw;
} else {
scaleFactor = targetSize/ih;
}
}
var iwAdj = Math.floor(iw*scaleFactor);
var ihAdj = Math.floor(ih*scaleFactor);
return {
ih: ihAdj, iw: iwAdj
}
};
};
return qDraw.promise;
}; // done
回答1:
The Cause
The reason is that the canvas has invalid size:
[...] The one exception to this is if the canvas has either no height or no width, in which case the result might simply be "data:,".
Invalid size is including anything < 1.
When an image element doesn't have data loaded the width and height properties are 0 by default until the image has been fully loaded and decoded into a bitmap, at which time triggers the onload
handler:
var img = new Image();
document.write("w: " + img.width + " h: " + img.height);
The Solution
Make sure the image has loaded before reading any size from it (simplified example, adopt as seen fit for your code):
var img = new Image();
var w, h;
img.onload = function() {
w = this.width; // here we can extract image size
h = this.height;
// set canvas size here as well before drawing the image in
// continue you code from here using f.ex. a callback
document.write("w: " + w + " h: " + h);
};
img.src = "http://i.imgur.com/eekEotAb.jpg"; // set src last
回答2:
The image has not yet fully loaded when you are calling resizeDimensions
. And you're attempting to resize the canvas before the img dimensions have been set.
Put that code inside your img.onload
handler so the image is guaranteed to be fully loaded.
来源:https://stackoverflow.com/questions/30079423/canvas-todataurl-returns-data