将位图RGB像素加载到BufferedImage中

时间:2014-10-08 14:57:08

标签: java colors bitmap rgb

所以我终于编写代码来检测我的位图的所有正确RGB值,并存储它们。

BufferedImage image = new BufferedImage(adjWidth, 
                                        this.height, 
                                        BufferedImage.TYPE_3BYTE_BGR);

// start from bottom row
for(int i = this.height-1; i >= 0; i--) {
    for(int j = 0; j < adjWidth-2; j += 3) {
        int index = adjWidth*i + j;
        int b = iData[index];
        int g = iData[index+1];
        int r = iData[index+2];
        int rgb = ((r&0x0ff)<<16)|((g&0x0ff)<<8)|(b&0x0ff); // merge rgb values to single int
        /*
        System.out.printf("\nRow: %s\nColumn: %s\nRed: %s\n"
                            + "Green: %s\nBlue: %s\n", i, j, 
                            (rgb>>16)&0x0ff, (rgb>>8)&0x0ff, (rgb)&0x0ff);
        System.out.println("Color value: " + rgb);
        */
        // build image from bottom up
        image.setRGB(j, this.height-i-1, rgb);
    }
}

iData是从文件中读取的byte []。我知道我的RGB值在调试它们的值后是正确的,并且还将它们与十六进制编辑器进行比较。 AdjWidth是包括填充的宽度。

然而,我的图像在整个图像中输出垂直黑带。当我将它与源图像进行比较时,我知道图像是部分正确的,虽然它有点扭曲,但我认为所有这些都来自这个问题。我怀疑这是因为j增加3,所以当我设置像素值时,它会跳过这些像素。如何避免这种情况,并创建正确的图像?

输入bmp:Input

输出bmp:  Output

修改 顺便说一下,我这样做是为了练习。

1 个答案:

答案 0 :(得分:1)

它可能缺少一些代码和进一步的解释,但是:你有一个数组,每个像素包含3个值。所以你在内循环中以j+=3递增。但是,输出图像应该只为每三个值接收一个像素。

所以你可以使用

image.setRGB(j/3, this.height-i-1, rgb);

或让循环遍历输出图像的大小,并在访问数组时将坐标乘以3,大致如下:

for(int j = 0; j < adjWidth-2; j++) {
    int index = (adjWidth*i + j) * 3;
    int b = iData[index];
    int g = iData[index+1];
    int r = iData[index+2];
    ...
    image.setRGB(j, this.height-i-1, rgb);
}

编辑:虽然创建一个数组并用像素填充它有点没有意义,但只是为了创建一个用相同数据填充的图像:这个程序用BGR填充bgr数组像素值应该从黑色水平延伸到蓝色水平,从黑色垂直延伸到绿色。然后使用该数组创建一个图像,该图像精确显示这些渐变。也许这个例子无论如何都会有所帮助。

import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class ImagePixelsTest {
    public static void main(String[] args) {

        int w = 256;
        int h = 256;
        byte bgr[] = new byte[w * h * 3];
        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                int index = (y * w + x) * 3;
                bgr[index + 0] = (byte) x;
                bgr[index + 1] = (byte) y;
                bgr[index + 2] = 0;
            }
        }

        final BufferedImage image = createImage(w, h, bgr);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.getContentPane().add(new JLabel(new ImageIcon(image)));
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }

    private static BufferedImage createImage(int w, int h, byte bgr[]) {
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);

        for (int y = h - 1; y >= 0; y--) {
            for (int x = 0; x < w; x++) {
                int index = (y * w + x) * 3;
                int b = bgr[index + 0];
                int g = bgr[index + 1];
                int r = bgr[index + 2];
                int rgb = ((r & 0x0ff) << 16) | ((g & 0x0ff) << 8) | (b & 0x0ff);
                image.setRGB(x, y, rgb);
            }
        }
        return image;
    }

}