Java 如何更改BuffereImage类型?

Java 如何更改BuffereImage类型?,java,image,graphics,bufferedimage,Java,Image,Graphics,Bufferedimage,我正在使用ImageIO导入图像,以将图像组件(alpha、红色、绿色、蓝色)存储在字节数组中。稍后我需要读取这个字节数组,但我不知道组件(我不知道第一个元素是alpha,第二个元素是红色…还是不在数组中)存储在哪个序列中,alpha甚至存储在哪个序列中 是否有默认序列?或者有没有办法将序列更改为所需的序列,如ABGR或ARGB等 获取阵列中组件的当前代码 BufferedImage temp; try{ temp = ImageIO.read(new File

我正在使用
ImageIO
导入图像,以将图像组件(alpha、红色、绿色、蓝色)存储在字节数组中。稍后我需要读取这个字节数组,但我不知道组件(我不知道第一个元素是alpha,第二个元素是红色…还是不在数组中)存储在哪个序列中,alpha甚至存储在哪个序列中

是否有默认序列?或者有没有办法将序列更改为所需的序列,如ABGR或ARGB等

获取阵列中组件的当前代码

    BufferedImage temp;

    try{
        temp = ImageIO.read(new File(path));
        ImageArray = ((DataBufferByte)temp.getRaster().getDataBuffer()).getData();
    }catch(IOException ex){
        ex.printStackTrace();
    }

java文档对我一点帮助都没有

java中的BuffereImage对象有两个相关方法:

int getRGB(int x, int y)

在这两种情况下,无论图片如何设置,像素通道始终遵循相同的方案。int rgb是一个四字节整数

最左边的字节是alpha,然后是红色、蓝色、绿色。也就是说,argb。因为一个字节可以容纳0到255之间的小整数。每个字节有256种不同的强度。实际位如下所示:

aaaaaaaarrrrrrrrggggggggbbbbbbbb
要提取要访问的颜色或alpha,请使用逐位运算符

例如,如果我只想要红色,我可以使用位移位运算符将位右移16位,然后使用十六进制值将其提取为该通道:

int rgb = image.getRGB(x, y);
int a = (rgb >> 24) & 0x000000ff;
int r = (rgb >> 16) & 0x000000ff;
int g = (rgb >>  8) & 0x000000ff;
int b =       (rgb) & 0x000000ff;
让我们看看结果如何。假设我们已经有了一种颜色:

rgb -> the binary 00101011 10101010 11111111 00000000
然后将其右移16位:

00000000 00000000 00101011 10101010
注意,现在阿尔法还在那里…我们不想要它。因此,我们将清除除红色位以外的所有内容,方法是将它们与之相加:

    00000000 00000000 00101011 10101010
and 00000000 00000000 00000000 11111111
  = 00000000 00000000 00000000 10101010
这只是颜色10101010的红色部分

您还可以使用相同的思路反向设置所有三个位通道:

int rgb = (a << 24) | (r << 16) | (g << 8) | b;

int rgb=(a请向我们展示您的代码如何将图像组件存储在字节数组中。@VGR代码已上载。现在我不知道组件如何在数组中排列。您的标题与您的问题无关。@EJP抱歉,我认为您不理解这个问题,简言之,问题是如果没有默认序列,那么如何将序列更改为默认序列所需的。很抱歉造成混淆。这意味着
数组[0]是alpha,数组[1]是红色,数组[2]是绿色,数组[3]是蓝色的
。对吗?如果我没记错的话,数据缓冲字节中的每个索引都只是一个字节。所以是的,每个像素应该有4个。我现在启动一个示例项目来确认,我会马上回复给你。所以,一旦你达到修改实际光栅中的字节的级别,这就是你正在做的,chan的大小nels和订单完全依赖于组件模型。这可以通过使用$img.getColorModel().getComponentSize()获得$call来自缓冲图像。如果您是通过其构造函数创建缓冲图像,则该格式将通过使用BuffereImage.TYPE传入。但是对于纹理映射,我认为在运行程序之前获取所有纹理的数据要比
getRGB
好,我错了吗?谢谢您的回答。我没有像以前那样关注优化这只是一个爱好项目,所以快速和肮脏对我来说没问题。
int rgb = (a << 24) | (r << 16) | (g << 8) | b;
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
// If we swap the type, what we put in our for loop will vary greatly
DataBufferByte dbb = ((DataBufferByte)img.getRaster().getDataBuffer());
byte[] bytes = dbb.getData();
for (int i = 0; i < bytes.length; i++) {
  // modify byte array here with bytes[i];
}
try {
  SampleModel sampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, 100, 100, 3, 100*3, new int[]{2, 1, 0});
  DataBuffer dataBuffer = new DataBufferByte(bytes, bytes.length);
  Raster raster = Raster.createRaster(sampleModel, dataBuffer, null);
  img.setData(raster);
} catch stuff......