Cropping Image inside promises using canvas not working
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
add a comment |
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
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
add a comment |
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
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
javascript canvas promise es6-promise
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 13 '18 at 10:29
community wiki
Kaiido
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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