React JS getImageData 对于所有 rgba 值都返回 0

问题描述 投票:0回答:1

尽管遇到了许多其他相关帖子和有用的解决方案,但我有一个问题似乎仍然存在。

我想根据每个像素的 Alpha 通道值为每个 png 创建一个嵌套数组。

这是我想要的一个较小的 5 x 5 结果示例:

[[1, 0, 1, 0, 1],
[0, 1, 0, 1, 0],
[1, 0, 1, 0, 1],
[0, 1, 0, 1, 0],
[1, 0, 1, 0, 1]]

嵌套数组中的值是 1 还是 0 取决于该像素的 alpha 值是否等于 255。如果像素是黑色,我希望嵌套数组中的特定值是 1。所有这些png 非常小,16 x 16 像素。

我创建这些数组的方法是将画布放入引用中,然后使用

.drawImage()
.getImageData()
来获取信息。

.getImageData()
有这些参数
(0, 0, 16, 16, {colorSpace: 'srgb'})
,希望 16 x 16 是捕获正确图像数据的正确尺寸。

在 CSS 文件中,我将画布设置为具有以下尺寸:

width: 260px; height: 150px;
希望这不会以任何方式妨碍
.getImageData()

我还确保使用

.onload
等待图像加载完成。加载时也会设置画布的尺寸。

我制作的图像具有透明背景,因为当我通过在画布上显示它们来测试它们时,图像的透明区域内没有不同的背景颜色。我还确保在保存这些图像时保留 Alpha 通道。

.getContext()
中,我确保将
alpha
设置为
true

下面是处理每个png的代码:

    function handleSubmit(event) {
        event.preventDefault();
        let convertedPresets = [];

        if (presetLayouts.length > 0) {

            for (let presetIndex = 0; presetIndex < presetLayouts.length; presetIndex++) {
                let newConvertedPreset = [];

                let img = new Image();
                img.crossOrigin = 'Anonymous';
                
                let ctx = canvasRef.current.getContext('2d', { alpha: true, desynchronized: false, colorSpace: 'srgb', willReadFrequently: true})
                ctx.globalCompositeOperation = "copy";

                let imageData;

                img.onload = function () {
                    ctx.width = img.width;
                    ctx.height = img.height;
                    
                    ctx.drawImage(img, 0, 0);
                    console.log(ctx)
                    imageData = ctx.getImageData(0, 0, 16, 16, {colorSpace: 'srgb'}).data;

                    for (let rowIndex = 0; rowIndex < 16; rowIndex++) {

                        let newRow = [];
                        
                        for (let i = 0; i < 64; i += 4) {
                            // every 4th imageData element is 
                            // the alpha channel for each pixel

                            if (imageData[i + 3] === 255) {
                                newRow.push(1);
                                

                            } else if (imageData[i + 3] === 0) {
                                newRow.push(0);
                            }

                        }

                        newConvertedPreset.push(newRow)

                    }

                }

                img.src = presetLayouts[presetIndex];

            }

            convertedPresets.push(newConvertedPreset)

        }

        ...

    }

下面是我尝试过的其他帖子中的两个解决方案,但没有成功,因为它们给了我相同的结果:

创建承诺

context.globalCompositeOperation =“复制”

如果您对可能缺少的内容有任何建议,请告诉我。

谢谢!

javascript arrays canvas alpha getimagedata
1个回答
0
投票

事实证明,我以一种一直得不到结果的方式迭代数据。

之前,它只迭代第一行,在这种情况下除了零之外不会返回任何内容(因为我从未在该区域上绘制过)。我从未将索引增加到超过第一行的起点。下面您可以看到更正:

function handleSubmit(event) {
        event.preventDefault();

        let convertedPresets = [];

        if (presetLayouts.length > 0) {

            for (let presetIndex = 0; presetIndex < presetLayouts.length; presetIndex++) {
                let newConvertedPreset = [];
                let presetSrc = presetLayouts[presetIndex].replace('/public', '')
                console.log(presetSrc)

                let img = new Image();
                img.crossOrigin='Anonymous';
                
                let ctx = canvasRef.current.getContext('2d', { alpha: true, desynchronized: false, colorSpace: 'srgb', willReadFrequently: true})
                ctx.globalCompositeOperation = "copy";

                let imageData;

                img.onload = function () {
                    console.log(img.width, img.height)
                    ctx.width = img.width;
                    ctx.height = img.height;
                    ctx.imageSmoothingEnabled = false;
                    
                    ctx.drawImage(img, 0, 0);
                    console.log(ctx)
                    imageData = ctx.getImageData(0, 0, 16, 16, {colorSpace: 'srgb'}).data;
                    console.log(imageData)
                    for (let rowIndex = 0; rowIndex < 16; rowIndex++) {

                        let newRow = [];
                        
                        // CORRECTED
                        for (let i = 0 + 64 * rowIndex; i < 64 + 64 * rowIndex; i += 4) {
                        // CORRECTED
                            // every 4th imageData element is 
                            // the alpha channel for each pixel
                            console.log('r', imageData[i])
                            console.log('g', imageData[i + 1])
                            console.log('b', imageData[i + 2])
                            console.log('a', imageData[i + 3])
                            if (imageData[i + 3] === 255) {
                                newRow.push(1);
                                

                            } else if (imageData[i + 3] === 0) {
                                newRow.push(0);
                            }

                        }

                        newConvertedPreset.push(newRow)

                    }

                    convertedPresets.push(newConvertedPreset)
                }

                img.src = presetLayouts[presetIndex];

            }

            

        }

这是一个愚蠢的错误,但我很高兴有这次学习经历。谢谢大家的建议!

© www.soinside.com 2019 - 2024. All rights reserved.