我在保存BMP文件时遇到问题。我需要使用4个颜色索引的调色板保存未压缩的BMP图像(BI_RGB)。
我有一个名为image
的BufferedImage对象(没关系,因为保存为png后看起来正确)。然后,我创建IndexColorModel并转换BufferedImage:
IndexColorModel colorModel = new IndexColorModel(
4, // 4 bits - max 16 colors
4, // 4 colors in palette
new byte[]{(byte) BITMAP_COLOR_1[0], (byte) BITMAP_COLOR_2[0], (byte) BITMAP_COLOR_3[0], (byte) BITMAP_COLOR_4[0]},
new byte[]{(byte) BITMAP_COLOR_1[1], (byte) BITMAP_COLOR_2[1], (byte) BITMAP_COLOR_3[1], (byte) BITMAP_COLOR_4[1]},
new byte[]{(byte) BITMAP_COLOR_1[2], (byte) BITMAP_COLOR_2[2], (byte) BITMAP_COLOR_3[2], (byte) BITMAP_COLOR_4[2]});
BufferedImage grayImage = new BufferedImage(
image.getWidth(), image.getHeight(),
BufferedImage.TYPE_BYTE_INDEXED,
colorModel);
Graphics2D gfx2d = grayImage.createGraphics();
gfx2d.setPaint(Color.WHITE);
gfx2d.fillRect(0, 0, grayImage.getWidth(), grayImage.getHeight());
gfx2d.drawImage(image, 0, 0, null);
gfx2d.dispose();
现在,当我将其保存为png时,它看起来不错,问题是当我尝试将其保存为BPM时,就像这样:
private byte[] createBmpBytes(BufferedImage image) {
byte[] data = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageWriter writer = ImageIO.getImageWritersByFormatName("BMP").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
writer.setOutput(ios);
BMPImageWriteParam param = (BMPImageWriteParam) writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionType("BI_RGB");
param.setTopDown(true);
writer.write(null, new IIOImage(image, null, null), param);
writer.dispose();
ios.flush();
data = baos.toByteArray();
ios.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return data;
}
当我将其保存为png时,它看起来像是:https://ibb.co/WpmYLcP
是某处参数错误,还是Java不支持这种BMP格式?是否有任何外部库可以这种格式保存BMP?
为了保存BMP,我使用了Apache Commons Imaging,结果与预期的一样。图像已保存为BI_RGB(采用压缩),并包含IndexColorModel的4种调色板。
private byte[] createBmpBytes(BufferedImage bufferedImage) {
Map<String, Object> params = new HashMap<String, Object>();
byte[] imageBytes = null;
try {
imageBytes = Imaging.writeImageToBytes(bufferedImage, ImageFormats.BMP, params);
} catch (ImageWriteException | IOException e) {
log.error("Image generating error", e);
}
return imageBytes;
}