Jef*_*let 23 arrays byte bufferedimage
我发布这个帖子是因为我在处理Java中的图片时遇到了一些困难.我希望能够将图片转换为byte []数组,然后才能进行反向操作,这样我就可以更改每个像素的RGB,然后创建一个新图片.我想使用这个解决方案,因为BufferedImage的setRGB()和getRGB()对于巨大的图片来说可能太慢了(如果我错了,请纠正我).
我在这里阅读了一些帖子来获取byte []数组(例如这里),以便每个像素由包含红色,绿色和蓝色值的数组的3或4个单元格表示(带有额外的alpha值,当有是4个细胞),这对我来说非常有用且易于使用.这是我用来获取这个数组的代码(存储在我创建的PixelArray类中):
public PixelArray(BufferedImage image)
{
width = image.getWidth();
height = image.getHeight();
DataBuffer toArray = image.getRaster().getDataBuffer();
array = ((DataBufferByte) toArray).getData();
hasAlphaChannel = image.getAlphaRaster() != null;
}
Run Code Online (Sandbox Code Playgroud)
我的大麻烦是我没有找到任何有效的方法将此byte []数组转换为新图像,如果我想转换图片(例如,删除蓝色/绿色值并仅保留红色值).我试过这些解决方案:
1)创建一个DataBuffer对象,然后创建一个SampleModel,最后创建一个WritableRaster,然后创建BufferedImage(带有额外的ColorModel和Hashtable对象).它没有用,因为我显然没有我需要的所有信息(我不知道什么是BufferedImage()构造函数的Hashtable).
2)使用ByteArrayInputStream.这不起作用,因为ByteArrayInputStream所期望的byte []数组与我的无关:它代表文件的每个字节,而不是每个像素的每个分量(每个像素有3-4个字节)......
有人能帮助我吗?
hee*_*ong 34
试试这个:
private BufferedImage createImageFromBytes(byte[] imageData) {
ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
try {
return ImageIO.read(bais);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 10
我尝试过这里提到的方法,但由于某些原因,它们都没有奏效.使用ByteArrayInputStream和ImageIO.read(...)返回null,而byte[] array = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();返回图像数据的副本,而不是直接引用它们(另请参见此处).
但是,以下工作对我有用.让我们假设图像数据的尺寸和类型是已知的.我们也是byte[] srcbuf要转换成数据的缓冲区BufferedImage.然后,
例如,创建一个空白图像
img=new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
Run Code Online (Sandbox Code Playgroud)将数据数组转换为Raster并用于setData填充图像,即
img.setData(Raster.createRaster(img.getSampleModel(), new DataBufferByte(srcbuf, srcbuf.length), new Point() ) );
Run Code Online (Sandbox Code Playgroud)BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
byte[] array = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(pixelArray, 0, array, 0, array.length);
Run Code Online (Sandbox Code Playgroud)
当您尝试使用生成的图像的Graphics对象时,此方法确实会失去同步.如果您需要在图像上绘制,请构建第二个图像(可以是持久的,即不是每次都构造但重新使用),drawImage第一个图像就是它.
有几个人赞成接受的答案是错误的评论。
如果接受的答案不起作用,可能是因为 Image.IO 不支持您正在尝试的图像类型,例如 tiff 图像。
要使其工作,您需要添加一个额外的 jar 来处理图像类型。
您可以添加jai-imageio-core-1.3.1.jar到您的类路径:
<!-- https://mvnrepository.com/artifact/com.github.jai-imageio/jai-imageio-core -->
<dependency>
<groupId>com.github.jai-imageio</groupId>
<artifactId>jai-imageio-core</artifactId>
<version>1.3.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
添加对以下内容的支持:
您可以通过以下方式查看支持的格式列表:
for(String format : ImageIO.getReaderFormatNames())
System.out.println(format);
Run Code Online (Sandbox Code Playgroud)
请注意,您只需将 jar(例如 jai-imageio-core-1.3.1.jar)放入类路径中即可使其工作。
其他为图像类型添加额外支持的项目包括: