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(您可以通过更改我的代码)

可以使此解决方案更有效