Java 将位图RGB像素加载到BuffereImage
因此,我最终编写了代码来检测位图的所有正确RGB值,并将其存储Java 将位图RGB像素加载到BuffereImage,java,colors,bitmap,rgb,Java,Colors,Bitmap,Rgb,因此,我最终编写了代码来检测位图的所有正确RGB值,并将其存储 BufferedImage image = new BufferedImage(adjWidth, this.height, BufferedImage.TYPE_3BYTE_BGR); // start from bottom row for(int i = this
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);
}
}
BufferedImage image=新的BufferedImage(adjWidth,
这个,身高,
buffereImage.TYPE_3BYTE_BGR);
//从最底层开始
对于(int i=this.height-1;i>=0;i--){
对于(int j=0;j
iData是从文件中读取的字节[]。我知道我的RGB值在调试完它们的值之后是正确的,并且将它们与十六进制编辑器进行了比较。AdjWidth是包含填充的宽度
但是,我的图像在整个图像上以垂直黑带输出。当我将图像与源图像进行比较时,我知道图像部分是正确的,尽管有点失真,但我认为所有这些源都来自这个问题。我怀疑这是因为j增加了3,所以当我设置像素值时,它会跳过那些像素。如何避免这种情况,并创建正确的图像
输入bmp:
输出bmp:
编辑
顺便说一句,我这样做是为了练习。它可能缺少一些代码和进一步的解释,但是:您有一个数组,每个像素包含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);
}
为什么不使用ImageIO.read()?我这样做是为了练习。您确定源图像是bgr 24位格式的吗?为什么你的目标BuffereImage是3BYTE_BGR而不是INT_RGB或INT_ARGB?是的,因为我已经正确读取了头。因为我以为位图是以3字节BGR格式存储像素的?然而,将格式更改为INT_RGB不会改变任何内容。“我知道java有原生bmp支持。”事实上,不,java没有bmp支持。我以前尝试过第一种方法,它给出了这个输出(如预期的那样):下一种方法给出了该图像的左三分之一在整个过程中复制三次。@TetraComputerTure添加了一个示例,也许会有帮助。哇,是的,确实有用。我终于做到了!!起初我使用了你的*3方法,但显然我没有考虑改变其余的变量,这次我考虑了,而且很有效!对非常感谢你!我知道这毫无意义,但这是理解文件格式的一个很好的练习,不是吗?(: @Marco13@Tetramputechture“无意义”一词指的是我的例子,在我的例子中,我必须创建数组,当然,我创建数组的方式可以在以后使用它的地方使用-但它有帮助,这才是最重要的;-)
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;
}
}