Cropping Image inside promises using canvas not working












0















I'm trying to crop multiple images using canvas and I want to run some other function after I'm done with cropping all the images.



This is my promise function to crop images



const checkImage = url => {
return new Promise(resolve => {
const workingURL = url;
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
const ctx = canvas.getContext('2d');
img = new Image();
img.setAttribute('crossOrigin', '');
img.onload = function(){
var w = img.width;
var h = img.height;

var rw = 200;
var rh = 200;

if (w > h) {
var ar = (w / h).toFixed(2);
var dar = (200/h);
rw = Math.floor(w * dar);
} else if (h > w) {
var ar = (h / w).toFixed(2);
var dar = (200/w);
rh = Math.floor(h * dar);
}

var sx = 200 / 2 - rw / 2;
var sy = 200 / 2 - rh / 2;
console.log(sx, sy, rw, rh);
console.log(img);
ctx.drawImage(img,sx,sy, rw , rh);
var s = canvas.toDataURL();
console.log('done cropping ', url, s);
resolve({url: workingURL, res: s});
}
img.onerror = (err) => {
console.log('onload error ',err);
resolve({url: workingURL, res: false});
};
img.src = url;
});
}


now I have couple of images need to be called, so I'm calling promise with each image



cropImageForGIFFn = () => {
const needCropImgs = [
{
"src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-Hrc7otKvJZTg6D5Rp.png",
},
{
"src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-ZAnRMDHfAGz2Xe9oX.png",
},
];
const needCropImgsLen = needCropImgs.length;
let resolvedPromises = 0;

needCropImgs.forEach(function (imgInfo) {
checkImage(imgInfo.src).then((info) => {
console.log('promise resolved');
console.log(info);

resolvedPromises += 1;
if (resolvedPromises === 1) {
document.getElementById('img1').src = info.res;
}

if (resolvedPromises === 2) {
document.getElementById('img2').src = info.res;
}
console.log({resolvedPromises});
if (resolvedPromises >= needCropImgsLen) {
console.log('all are resolved');
}
});
});
};


I'm checking all promises are resolved or not and then calling some other function.



If I send multiple images to my promises function, first image is coming as transparent if I send only one image then everything working fine.



If I comment any of the images then cropping works fine.



I created Codepen here https://codepen.io/sasikanth1/pen/rQjxXL



try commenting one of the array values of needCropImgs then image will be displayed fine.










share|improve this question























  • It seems like your main problem is the use of implicit globals, but it also seems that your codepen doesn't work because the images are failing to load due to a CORS error.

    – JLRishe
    Nov 13 '18 at 10:40


















0















I'm trying to crop multiple images using canvas and I want to run some other function after I'm done with cropping all the images.



This is my promise function to crop images



const checkImage = url => {
return new Promise(resolve => {
const workingURL = url;
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
const ctx = canvas.getContext('2d');
img = new Image();
img.setAttribute('crossOrigin', '');
img.onload = function(){
var w = img.width;
var h = img.height;

var rw = 200;
var rh = 200;

if (w > h) {
var ar = (w / h).toFixed(2);
var dar = (200/h);
rw = Math.floor(w * dar);
} else if (h > w) {
var ar = (h / w).toFixed(2);
var dar = (200/w);
rh = Math.floor(h * dar);
}

var sx = 200 / 2 - rw / 2;
var sy = 200 / 2 - rh / 2;
console.log(sx, sy, rw, rh);
console.log(img);
ctx.drawImage(img,sx,sy, rw , rh);
var s = canvas.toDataURL();
console.log('done cropping ', url, s);
resolve({url: workingURL, res: s});
}
img.onerror = (err) => {
console.log('onload error ',err);
resolve({url: workingURL, res: false});
};
img.src = url;
});
}


now I have couple of images need to be called, so I'm calling promise with each image



cropImageForGIFFn = () => {
const needCropImgs = [
{
"src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-Hrc7otKvJZTg6D5Rp.png",
},
{
"src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-ZAnRMDHfAGz2Xe9oX.png",
},
];
const needCropImgsLen = needCropImgs.length;
let resolvedPromises = 0;

needCropImgs.forEach(function (imgInfo) {
checkImage(imgInfo.src).then((info) => {
console.log('promise resolved');
console.log(info);

resolvedPromises += 1;
if (resolvedPromises === 1) {
document.getElementById('img1').src = info.res;
}

if (resolvedPromises === 2) {
document.getElementById('img2').src = info.res;
}
console.log({resolvedPromises});
if (resolvedPromises >= needCropImgsLen) {
console.log('all are resolved');
}
});
});
};


I'm checking all promises are resolved or not and then calling some other function.



If I send multiple images to my promises function, first image is coming as transparent if I send only one image then everything working fine.



If I comment any of the images then cropping works fine.



I created Codepen here https://codepen.io/sasikanth1/pen/rQjxXL



try commenting one of the array values of needCropImgs then image will be displayed fine.










share|improve this question























  • It seems like your main problem is the use of implicit globals, but it also seems that your codepen doesn't work because the images are failing to load due to a CORS error.

    – JLRishe
    Nov 13 '18 at 10:40
















0












0








0








I'm trying to crop multiple images using canvas and I want to run some other function after I'm done with cropping all the images.



This is my promise function to crop images



const checkImage = url => {
return new Promise(resolve => {
const workingURL = url;
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
const ctx = canvas.getContext('2d');
img = new Image();
img.setAttribute('crossOrigin', '');
img.onload = function(){
var w = img.width;
var h = img.height;

var rw = 200;
var rh = 200;

if (w > h) {
var ar = (w / h).toFixed(2);
var dar = (200/h);
rw = Math.floor(w * dar);
} else if (h > w) {
var ar = (h / w).toFixed(2);
var dar = (200/w);
rh = Math.floor(h * dar);
}

var sx = 200 / 2 - rw / 2;
var sy = 200 / 2 - rh / 2;
console.log(sx, sy, rw, rh);
console.log(img);
ctx.drawImage(img,sx,sy, rw , rh);
var s = canvas.toDataURL();
console.log('done cropping ', url, s);
resolve({url: workingURL, res: s});
}
img.onerror = (err) => {
console.log('onload error ',err);
resolve({url: workingURL, res: false});
};
img.src = url;
});
}


now I have couple of images need to be called, so I'm calling promise with each image



cropImageForGIFFn = () => {
const needCropImgs = [
{
"src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-Hrc7otKvJZTg6D5Rp.png",
},
{
"src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-ZAnRMDHfAGz2Xe9oX.png",
},
];
const needCropImgsLen = needCropImgs.length;
let resolvedPromises = 0;

needCropImgs.forEach(function (imgInfo) {
checkImage(imgInfo.src).then((info) => {
console.log('promise resolved');
console.log(info);

resolvedPromises += 1;
if (resolvedPromises === 1) {
document.getElementById('img1').src = info.res;
}

if (resolvedPromises === 2) {
document.getElementById('img2').src = info.res;
}
console.log({resolvedPromises});
if (resolvedPromises >= needCropImgsLen) {
console.log('all are resolved');
}
});
});
};


I'm checking all promises are resolved or not and then calling some other function.



If I send multiple images to my promises function, first image is coming as transparent if I send only one image then everything working fine.



If I comment any of the images then cropping works fine.



I created Codepen here https://codepen.io/sasikanth1/pen/rQjxXL



try commenting one of the array values of needCropImgs then image will be displayed fine.










share|improve this question














I'm trying to crop multiple images using canvas and I want to run some other function after I'm done with cropping all the images.



This is my promise function to crop images



const checkImage = url => {
return new Promise(resolve => {
const workingURL = url;
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
const ctx = canvas.getContext('2d');
img = new Image();
img.setAttribute('crossOrigin', '');
img.onload = function(){
var w = img.width;
var h = img.height;

var rw = 200;
var rh = 200;

if (w > h) {
var ar = (w / h).toFixed(2);
var dar = (200/h);
rw = Math.floor(w * dar);
} else if (h > w) {
var ar = (h / w).toFixed(2);
var dar = (200/w);
rh = Math.floor(h * dar);
}

var sx = 200 / 2 - rw / 2;
var sy = 200 / 2 - rh / 2;
console.log(sx, sy, rw, rh);
console.log(img);
ctx.drawImage(img,sx,sy, rw , rh);
var s = canvas.toDataURL();
console.log('done cropping ', url, s);
resolve({url: workingURL, res: s});
}
img.onerror = (err) => {
console.log('onload error ',err);
resolve({url: workingURL, res: false});
};
img.src = url;
});
}


now I have couple of images need to be called, so I'm calling promise with each image



cropImageForGIFFn = () => {
const needCropImgs = [
{
"src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-Hrc7otKvJZTg6D5Rp.png",
},
{
"src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-ZAnRMDHfAGz2Xe9oX.png",
},
];
const needCropImgsLen = needCropImgs.length;
let resolvedPromises = 0;

needCropImgs.forEach(function (imgInfo) {
checkImage(imgInfo.src).then((info) => {
console.log('promise resolved');
console.log(info);

resolvedPromises += 1;
if (resolvedPromises === 1) {
document.getElementById('img1').src = info.res;
}

if (resolvedPromises === 2) {
document.getElementById('img2').src = info.res;
}
console.log({resolvedPromises});
if (resolvedPromises >= needCropImgsLen) {
console.log('all are resolved');
}
});
});
};


I'm checking all promises are resolved or not and then calling some other function.



If I send multiple images to my promises function, first image is coming as transparent if I send only one image then everything working fine.



If I comment any of the images then cropping works fine.



I created Codepen here https://codepen.io/sasikanth1/pen/rQjxXL



try commenting one of the array values of needCropImgs then image will be displayed fine.







javascript canvas promise es6-promise






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 9:17









SasikanthSasikanth

2,62011242




2,62011242













  • It seems like your main problem is the use of implicit globals, but it also seems that your codepen doesn't work because the images are failing to load due to a CORS error.

    – JLRishe
    Nov 13 '18 at 10:40





















  • It seems like your main problem is the use of implicit globals, but it also seems that your codepen doesn't work because the images are failing to load due to a CORS error.

    – JLRishe
    Nov 13 '18 at 10:40



















It seems like your main problem is the use of implicit globals, but it also seems that your codepen doesn't work because the images are failing to load due to a CORS error.

– JLRishe
Nov 13 '18 at 10:40







It seems like your main problem is the use of implicit globals, but it also seems that your codepen doesn't work because the images are failing to load due to a CORS error.

– JLRishe
Nov 13 '18 at 10:40














1 Answer
1






active

oldest

votes


















1














Typo,

You forgot a const or let or var before img declaration.



   img = new Image();
// ^- scope leak


This means your img variable in all the async callbacks will refer to the latest declared Image(). This could indeed lead to some transparent result if the last image didn't load before the other ones.



So simply add this keyword and you'll be fine.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53277556%2fcropping-image-inside-promises-using-canvas-not-working%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Typo,

    You forgot a const or let or var before img declaration.



       img = new Image();
    // ^- scope leak


    This means your img variable in all the async callbacks will refer to the latest declared Image(). This could indeed lead to some transparent result if the last image didn't load before the other ones.



    So simply add this keyword and you'll be fine.






    share|improve this answer






























      1














      Typo,

      You forgot a const or let or var before img declaration.



         img = new Image();
      // ^- scope leak


      This means your img variable in all the async callbacks will refer to the latest declared Image(). This could indeed lead to some transparent result if the last image didn't load before the other ones.



      So simply add this keyword and you'll be fine.






      share|improve this answer




























        1












        1








        1







        Typo,

        You forgot a const or let or var before img declaration.



           img = new Image();
        // ^- scope leak


        This means your img variable in all the async callbacks will refer to the latest declared Image(). This could indeed lead to some transparent result if the last image didn't load before the other ones.



        So simply add this keyword and you'll be fine.






        share|improve this answer















        Typo,

        You forgot a const or let or var before img declaration.



           img = new Image();
        // ^- scope leak


        This means your img variable in all the async callbacks will refer to the latest declared Image(). This could indeed lead to some transparent result if the last image didn't load before the other ones.



        So simply add this keyword and you'll be fine.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        answered Nov 13 '18 at 10:29


























        community wiki





        Kaiido































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53277556%2fcropping-image-inside-promises-using-canvas-not-working%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            The Sandy Post

            Danny Elfman

            Pages that link to "Head v. Amoskeag Manufacturing Co."