below is my javascript code which i use for combining 64 images to generate a panorama image. but when i load it first time it gives me broken image however at seconds or third time it gives me right image. In Below combine function do all image combine process, combinedArray contains all urls of images.
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;
}
Can you try this -
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);
It is not the most efficient way of using promises. I only used async-await feature to make sure image components are getting loaded in sequence.
As an example this solution might be made more efficient by using Promise.All API (you can it by altering my code)