为什么这个代码不下载25张图片,而是下载15到20张



我想把一个图像切成小图像,以便制作一个谜题。我写了图像url,画布的大小与图像相同,然后我重新加载页面,我应该有25个大图像的裁剪图像。

问题是它没有下载25个图像,有时它会从图像19跳到图像25。我必须重新加载页面,多次,以拥有所有的图像。你知道为什么吗?是因为这里直接调用了函数吗:

promises.push(getCanvas(canvas, j*w, i*h, w, h, countImg));

为了测试它,你需要使用像MAMP(mac(这样的本地服务器。首先,我们将大图像加载到画布中,然后存储将占用大图像一小部分的每个promise,然后使用promise.all。console.log("test"(显示25次。但我只下载了15到20张图片。

<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>

编辑:

因此,基于您的代码,它下载";IMAGE25.png";13次,或随机次数:

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'))
}
}

代码本身很好,您可以添加一些"控制台日志";或者调试它,看看实际发生了什么。您还可以添加";尝试捕获";并记录在getCanvas函数中捕获的任何错误。

const row = 5
const promises = [];
let countImg = 0;
let cut = row;
let w = Math.floor(500 / cut); //we cut the big image in small parts
let h = Math.floor(500 / cut);
for (let i=0; i<cut; i++){
for (let j=0; j<cut; j++){
countImg++;
promises.push(getCanvas({}, 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){
return new Promise((resolve) => {
console.log(index, posX, posY, width, height);
resolve("ok");
});
}

潜在的问题可能是一次请求太多(然后其中一些请求可能会停止(。试着把它们分成更小的块(即一次5个(,等待块完成后再继续新的块。

如果你想要更好的(但可能更难理解和使用(,你可以使用:https://caolan.github.io/async/v3/parallelLimit.js.html

您将创建promise(而不是promise本身(的函数数组放在那里,它将只执行一定数量的promise。一旦其中一个完成,就开始另一个。

这是一个创建函数数组的简单示例,您可以稍后以自己喜欢的方式执行这些函数。我的例子只是一个接一个地执行,但您可以更新该函数,使其按5获取块,并一次等待所有块。

const row = 5
const promises = [];
const fns = [];
let countImg = 0;
let cut = row;
let w = Math.floor(500 / cut); //we cut the big image in small parts
let h = Math.floor(500 / cut);
for (let i=0; i<cut; i++){
for (let j=0; j<cut; j++){
countImg++;
fns.push(() => getCanvas({}, 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'))

function getCanvas(canvas, posX, posY, width, height, index){
return new Promise((resolve) => {
console.log(index, posX, posY, width, height);
resolve("ok");
});
}

最新更新