所以我终于编写代码来检测我的位图的所有正确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:
输出bmp:
修改 顺便说一下,我这样做是为了练习。
答案 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;
}
}