I would like to cut an image into small images, in order to make a puzzle. I write the image url, the size of the canvas which is the same as the image, then I reload the page, and I should have 25 cropped images of the big image.
The issue is that it does not download 25 images, sometimes it jumps from image19 to image25. I have to reload the page again, multiple times, to have all the images. Would you know why? Is it because the function is directly called here :
promises.push(getCanvas(canvas, j*w, i*h, w, h, countImg));
?
In order to test it, you need to use a local server like MAMP (mac). First we load the big image in a canvas, then we store each promise that will take a small part of the big image, and we use Promise.all . The console.log("test") shows up 25 times. But I only have 15 to 20 images downloaded.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas width="560" height="647" id="test"></canvas>
<img src="#" id="captured" alt="">
<script>
let url = 're.png'; //the big image
let tab = new Array();
let countImg = 0, countClick = 0, row = 5;
var canvas = document.getElementById('test');
var ctx = canvas.getContext('2d');
let promises = new Array();
fillWithImage();
function fillWithImage(){ //fill the canvas with the big image
var base_image = new Image();
base_image.src = url;
base_image.crossOrigin = "Anonymous";
base_image.onload = function(){
ctx.drawImage(base_image, 0, 0);
let cut = row;
let w = Math.floor(base_image.width / cut); //we cut the big image in small parts
let h = Math.floor(base_image.height / cut);
for (let i=0; i<cut; i++){
for (let j=0; j<cut; j++){
countImg++;
promises.push(getCanvas(canvas, j*w, i*h, w, h, countImg));
}
}
Promise.all(promises).then(() => console.log('All transaction requests resolved'))
}
}
function getCanvas(canvas, posX, posY, width, height, index){ //we cut a small part
return new Promise((resolve, reject) => {
var context = canvas.getContext('2d');
var imageData = context.getImageData(posX, posY, width, height).data;
var outputCanvas = document.createElement('canvas');//2nd canvas created
var outputContext = outputCanvas.getContext('2d');
outputCanvas.width = width;
outputCanvas.height = height;
var idata = outputContext.createImageData(width, height);
idata.data.set(imageData);
outputContext.putImageData(idata, 0, 0);
var anchor = document.createElement("a");
console.log("test");//prints 25
anchor.href = outputCanvas.toDataURL("image/png");
anchor.download = "IMAGE"+index+".PNG";
anchor.click();
resolve("ok");
});
}
</script>
</body>
</html>
EDIT :
So based on your code, it downloads "IMAGE25.png" 13 times, or a random number of times :
function fillWithImage(){
var base_image = new Image();
base_image.src = url;
base_image.crossOrigin = "Anonymous";
base_image.onload = function(){
ctx.drawImage(base_image, 0, 0);
let cut = row;
let w = Math.floor(base_image.width / cut);
let h = Math.floor(base_image.height / cut);
let fns = [];
for (let i=0; i<cut; i++){
for (let j=0; j<cut; j++){
countImg++;
fns.push(() => getCanvas(canvas, j*w, i*h, w, h, countImg));
}
}
async function goAhead (fnsToExecute) {
for (let i=0; i < fns.length; i++) {
await fnsToExecute[i]();
}
}
goAhead(fns).then(() => console.log('All transaction requests resolved'))
}
}