读取PNG文件:BitmapFactory vs ImageIO

时间:2014-06-16 09:13:10

标签: java android javax.imageio bitmapfactory

我正在尝试使用ImageIO读取和修改png图像,并将其作为Android中的可绘制资源读取。

现在java代码看起来像这样:

BufferedImage im = ImageIO.read(new File(inFilePath));
WritableRaster raster = image.getRaster();
DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer();
byte imBytes[] = buffer.getData();

这为示例文件提供了一个大小约为140k的字节数组。 接下来我尝试用BitmapFactory读取它:

Drawable drawable = context.getResources().getDrawable(getImageResourceIdWithKeys());
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 200, stream);
byte[] imBytes = stream.toByteArray();

这给了我一个大小约为52k的字节数组,接下来将它作为原始资源读取,它提供了大约24k这是磁盘上的大小。现在我明白PNG文件是在磁盘上压缩的,但我无法理解为什么在获取未压缩版本时我得到不同的字节数组。有没有办法在Android上以相同的方式读取图像并使用标准Java API?

1 个答案:

答案 0 :(得分:0)

你在这里比较苹果和橘子。

在您的第一个(ImageIO / BufferedImage)示例中,imBytes是未压缩的像素数据(可能是RGB或ARGB格式,但它取决于输入)。

在您的第二个(Android /位图)示例中,imBytes是PNG压缩数据,由Android压缩并使用默认设置。在Android上读取/解码后,图像数据可能会扩展为ARGB,因此您的输出将是(A)RGB PNG。这可能需要比原始输入更多的字节,特别是如果磁盘上的原始文件是调色板格式。

Java2D和Android平台有不同的图形基元,所以我不确定你将如何满足"以相同的方式阅读图像" ...无论如何,BitmapFactory是可能是您在Android上获得相当于ImageIO的最接近的。同样,Bitmap大致相当于BufferedImage

IE中。的ImageIO / Java2D的:

BufferedImage im = ImageIO.read(new File(inFilePath));

int[] argbPixels = new int[im.getWidth() * im.getHeight()]; // Could also let getRGB allocate this array, but doing it like this to make it more similar to Android
im.getRGB(0, 0, im.getWidth(), im.getHeight(), argbPixels, 0, im.getWidth());

机器人:

Bitmap bm = BitmapFactory.decodeFile(inFilePath);

int[] argbPixels = new int[bm.getWidth() * bm.getHeight()];
bm.getPixels(argbPixels, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight();

不确定Android,但至少Java2D会在sRGB色彩空间中返回ARGB值。如果Android做同样的事情,argbPixels数组应该是相同的。