javascript 承诺在图像组合时无法按预期工作
javascript promises does not work as expected while image combining
下面是我的 javascript 代码,我用它来组合 64 张图像以生成全景图像。但是当我第一次加载它时,它给了我破损的图像,但是在几秒钟或第三次它给了我正确的图像。
在下面的合并功能中执行所有图像合并过程,
combinedArray 包含所有图片的 url。
function combine(imgSources, width, height, right, left) {
return Promise.all(imgSources.map(function (url) {
return new Promise(function (resolve) {
let img = new Image();
img.crossOrigin = `anonymous`;
img.src = url;
img.onload = function () {resolve(img);};
});
})).then(function (images) {
let canvas = document.createElement(`canvas`);
canvas.width = width;
canvas.height = height;
// draw images to the canvas
let ctx = canvas.getContext(`2d`);
for (let i = 0; i < imgSources.length; i++) {
ctx.drawImage(images[i], right * i, left * i);
}
// return the resulting image in base64 form
return canvas.toDataURL(`image/jpeg`);
});
}
function generateParonama(angle = 10) {
let url=`https://cdn.yourvrtours.com/000679.fcf5f084b8794573a6789774f9bfcbaf.1122/A4CDD7C7-3F58-435A-9A5B-9522078DE10B/optimized/Point_7537F461-3868-4EFB-9B82-3A1E3CF81955/3/`;
let mainImage;
let allSides = [`f`, `r`, `b`, `l`];
let allImages = [];
let combinedArray = [];
let ind = 0;
// generates array for all 64 images
function genareteArray() {
for (let index = 0; index < allSides.length; index++) {
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
let t = `${url + allSides[index] + j + '_' + i}.jpg`;
combinedArray.push(t);
}
}
}
}
// arrange array at given angle
function reArrangeArray() {
let position = 0 / 22.5;
let array2 = [];
if (position <= 8) {
position = (position + 8) * 4;
array2 = combinedArray.slice(position, 64);
combinedArray.splice(position)
combinedArray = array2.concat(combinedArray)
}
else {
position = (position - 8) * 4;
array2 = combinedArray.slice(0, position);
combinedArray.push(array2)
}
}
genareteArray();
reArrangeArray();
allSides.map((side, i) => {
return new Promise((res) => {
for (let index = 0; index < 4; index++) {
combine(
[
combinedArray[0 + ind],
combinedArray[1 + ind],
combinedArray[2 + ind],
combinedArray[3 + ind],
], 512, 2048, 0, 512)
.then(function (result) {
// result will be a column of 512 box
allImages.push(result);
if (allImages.length > 15) {
combine(allImages, 8192, 2048, 512, 0).then((r) => {
var img = new Image();
img.src = r;
document.body.appendChild(img);
});
}
});
ind = ind + 4;
}
});
});
}
generateParonama(10);
img{
max-width:600px;
}
你能试试这个吗-
function combine(imgSources, width, height, right, left) {
return Promise.all(imgSources.map(function (url) {
return new Promise(function (resolve) {
let img = new Image();
img.crossOrigin = `anonymous`;
img.src = url;
img.onload = function () { resolve(img); };
});
})).then(function (images) {
let canvas = document.createElement(`canvas`);
canvas.width = width;
canvas.height = height;
// draw images to the canvas
let ctx = canvas.getContext(`2d`);
for (let i = 0; i < imgSources.length; i++) {
ctx.drawImage(images[i], right * i, left * i);
}
// return the resulting image in base64 form
return canvas.toDataURL(`image/jpeg`);
});
}
async function generateParonama(angle = 10) {
let url = `https://cdn.yourvrtours.com/000679.fcf5f084b8794573a6789774f9bfcbaf.1122/A4CDD7C7-3F58-435A-9A5B-9522078DE10B/optimized/Point_7537F461-3868-4EFB-9B82-3A1E3CF81955/3/`;
let mainImage;
let allSides = [`f`, `r`, `b`, `l`];
let allImages = [];
let combinedArray = [];
let ind = 0;
// generates array for all 64 images
function genareteArray() {
for (let index = 0; index < allSides.length; index++) {
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
let t = `${url + allSides[index] + j + '_' + i}.jpg`;
combinedArray.push(t);
}
}
}
}
// arrange array at given angle
function reArrangeArray() {
let position = 0 / 22.5;
let array2 = [];
if (position <= 8) {
position = (position + 8) * 4;
array2 = combinedArray.slice(position, 64);
combinedArray.splice(position)
combinedArray = array2.concat(combinedArray)
}
else {
position = (position - 8) * 4;
array2 = combinedArray.slice(0, position);
combinedArray.push(array2)
}
}
genareteArray();
reArrangeArray();
console.log(combinedArray);
for (let i = 0; i < allSides.length; i++) {
const side = allSides[i];
for (let index = 0; index < 4; index++) {
var result = await combine(
[
combinedArray[0 + ind],
combinedArray[1 + ind],
combinedArray[2 + ind],
combinedArray[3 + ind],
], 512, 2048, 0, 512);
// result will be a column of 512 box
allImages.push(result);
if (allImages.length > 15) {
var r = await combine(allImages, 8192, 2048, 512, 0);
var img = new Image();
img.src = r;
document.body.appendChild(img);
}
ind = ind + 4;
}
}
}
generateParonama(10);
这不是使用 promise 的最有效方式。我只使用异步等待功能来确保图像组件按顺序加载。
例如,使用 Promise.All API(您可以通过更改我的代码)
可以使此解决方案更有效
下面是我的 javascript 代码,我用它来组合 64 张图像以生成全景图像。但是当我第一次加载它时,它给了我破损的图像,但是在几秒钟或第三次它给了我正确的图像。 在下面的合并功能中执行所有图像合并过程, combinedArray 包含所有图片的 url。
function combine(imgSources, width, height, right, left) {
return Promise.all(imgSources.map(function (url) {
return new Promise(function (resolve) {
let img = new Image();
img.crossOrigin = `anonymous`;
img.src = url;
img.onload = function () {resolve(img);};
});
})).then(function (images) {
let canvas = document.createElement(`canvas`);
canvas.width = width;
canvas.height = height;
// draw images to the canvas
let ctx = canvas.getContext(`2d`);
for (let i = 0; i < imgSources.length; i++) {
ctx.drawImage(images[i], right * i, left * i);
}
// return the resulting image in base64 form
return canvas.toDataURL(`image/jpeg`);
});
}
function generateParonama(angle = 10) {
let url=`https://cdn.yourvrtours.com/000679.fcf5f084b8794573a6789774f9bfcbaf.1122/A4CDD7C7-3F58-435A-9A5B-9522078DE10B/optimized/Point_7537F461-3868-4EFB-9B82-3A1E3CF81955/3/`;
let mainImage;
let allSides = [`f`, `r`, `b`, `l`];
let allImages = [];
let combinedArray = [];
let ind = 0;
// generates array for all 64 images
function genareteArray() {
for (let index = 0; index < allSides.length; index++) {
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
let t = `${url + allSides[index] + j + '_' + i}.jpg`;
combinedArray.push(t);
}
}
}
}
// arrange array at given angle
function reArrangeArray() {
let position = 0 / 22.5;
let array2 = [];
if (position <= 8) {
position = (position + 8) * 4;
array2 = combinedArray.slice(position, 64);
combinedArray.splice(position)
combinedArray = array2.concat(combinedArray)
}
else {
position = (position - 8) * 4;
array2 = combinedArray.slice(0, position);
combinedArray.push(array2)
}
}
genareteArray();
reArrangeArray();
allSides.map((side, i) => {
return new Promise((res) => {
for (let index = 0; index < 4; index++) {
combine(
[
combinedArray[0 + ind],
combinedArray[1 + ind],
combinedArray[2 + ind],
combinedArray[3 + ind],
], 512, 2048, 0, 512)
.then(function (result) {
// result will be a column of 512 box
allImages.push(result);
if (allImages.length > 15) {
combine(allImages, 8192, 2048, 512, 0).then((r) => {
var img = new Image();
img.src = r;
document.body.appendChild(img);
});
}
});
ind = ind + 4;
}
});
});
}
generateParonama(10);
img{
max-width:600px;
}
你能试试这个吗-
function combine(imgSources, width, height, right, left) {
return Promise.all(imgSources.map(function (url) {
return new Promise(function (resolve) {
let img = new Image();
img.crossOrigin = `anonymous`;
img.src = url;
img.onload = function () { resolve(img); };
});
})).then(function (images) {
let canvas = document.createElement(`canvas`);
canvas.width = width;
canvas.height = height;
// draw images to the canvas
let ctx = canvas.getContext(`2d`);
for (let i = 0; i < imgSources.length; i++) {
ctx.drawImage(images[i], right * i, left * i);
}
// return the resulting image in base64 form
return canvas.toDataURL(`image/jpeg`);
});
}
async function generateParonama(angle = 10) {
let url = `https://cdn.yourvrtours.com/000679.fcf5f084b8794573a6789774f9bfcbaf.1122/A4CDD7C7-3F58-435A-9A5B-9522078DE10B/optimized/Point_7537F461-3868-4EFB-9B82-3A1E3CF81955/3/`;
let mainImage;
let allSides = [`f`, `r`, `b`, `l`];
let allImages = [];
let combinedArray = [];
let ind = 0;
// generates array for all 64 images
function genareteArray() {
for (let index = 0; index < allSides.length; index++) {
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
let t = `${url + allSides[index] + j + '_' + i}.jpg`;
combinedArray.push(t);
}
}
}
}
// arrange array at given angle
function reArrangeArray() {
let position = 0 / 22.5;
let array2 = [];
if (position <= 8) {
position = (position + 8) * 4;
array2 = combinedArray.slice(position, 64);
combinedArray.splice(position)
combinedArray = array2.concat(combinedArray)
}
else {
position = (position - 8) * 4;
array2 = combinedArray.slice(0, position);
combinedArray.push(array2)
}
}
genareteArray();
reArrangeArray();
console.log(combinedArray);
for (let i = 0; i < allSides.length; i++) {
const side = allSides[i];
for (let index = 0; index < 4; index++) {
var result = await combine(
[
combinedArray[0 + ind],
combinedArray[1 + ind],
combinedArray[2 + ind],
combinedArray[3 + ind],
], 512, 2048, 0, 512);
// result will be a column of 512 box
allImages.push(result);
if (allImages.length > 15) {
var r = await combine(allImages, 8192, 2048, 512, 0);
var img = new Image();
img.src = r;
document.body.appendChild(img);
}
ind = ind + 4;
}
}
}
generateParonama(10);
这不是使用 promise 的最有效方式。我只使用异步等待功能来确保图像组件按顺序加载。
例如,使用 Promise.All API(您可以通过更改我的代码)
可以使此解决方案更有效