最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - canvas.toDataUrl() returns 'data:,' - Stack Overflow

programmeradmin1浏览0评论

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

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
Share asked May 6, 2015 at 14:17 WJAWJA 7,00420 gold badges98 silver badges170 bronze badges 3
  • 2 Where is the rest of the code doing canvas to dataurl? Right now it sounds like a race issue, do you have it called on ready/load? Or an ajax function? – David Nguyen Commented May 6, 2015 at 14:22
  • I use angular and call the function drawAndResizFunction from my controller. This function is available in the service. Do you need the HTML? – WJA Commented May 6, 2015 at 14:25
  • The strange thing is that it does not always happen... – WJA Commented May 6, 2015 at 14:30
Add a ment  | 

2 Answers 2

Reset to default 8

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./eekEotAb.jpg";  // set src last

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.

发布评论

评论列表(0)

  1. 暂无评论