【问题标题】:Java - Convert RAW to JPG/PNGJava - 将 RAW 转换为 JPG/PNG
【发布时间】:2015-10-06 01:36:28
【问题描述】:

我有一张由相机拍摄的图像,格式为 RAW BGRA(字节数组)。 如何将其作为JPG/PNG 文件保存到磁盘?

我已尝试使用 Java API 中的 ImageIO.write,但出现错误 IllegalArgumentException (image = null)

代码:

try
{
    InputStream input = new ByteArrayInputStream(img);
    BufferedImage bImageFromConvert = ImageIO.read(input);

    String path = "D:/image.jpg";

    ImageIO.write(bImageFromConvert, "jpg", new File(path));
}
catch(Exception ex)
{
    System.out.println(ex.toString());
}

请注意,“img”是 RAW 字节数组,它不为空。

【问题讨论】:

  • 如果ImageIO.write(...) 抱怨image == null,那意味着你没有图像。你能展示一下你用来读取原始图像的代码吗?

标签: java image png jpeg


【解决方案1】:

问题在于ImageIO.read 确实支持原始 RGB(或在您的情况下为 BGRA)像素。它需要文件格式,例如 BMP、PNG 或 JPEG 等。

在您上面的代码中,这会导致 bImageFromConvert 变为 null,这就是您看到错误的原因。

如果你有一个 BGRA 格式的 byte 数组,试试这个:

// You need to know width/height of the image
int width = ...;
int height = ...;

int samplesPerPixel = 4;
int[] bandOffsets = {2, 1, 0, 3}; // BGRA order

byte[] bgraPixelData = new byte[width * height * samplesPerPixel];

DataBuffer buffer = new DataBufferByte(bgraPixelData, bgraPixelData.length);
WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, samplesPerPixel * width, samplesPerPixel, bandOffsets, null);

ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);

BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);

System.out.println("image: " + image); // Should print: image: BufferedImage@<hash>: type = 0 ...

ImageIO.write(image, "PNG", new File(path));

请注意,JPEG 不是用于存储带有 Alpha 通道的图像的好格式。虽然有可能,但大多数软件都不会正确显示它。所以我建议改用PNG。

或者,您可以删除 Alpha 通道,并使用 JPEG。

【讨论】:

  • 是的,删除 alpha!什么样的相机可以拍出带有 alpha 信息的照片? (JPEG 和 PNG 之间的选择取决于一定的数据丢失是否比最终文件大小更可取。)
  • @Jongware 好点。我也想知道这一点。可能出于性能原因,相机仅使用 32 位对齐。
  • 谢谢,我试过你的代码,但如果我选择 PNG 格式,它会在磁盘上存储一个透明图像,如果我选择 JPG 格式,它会存储一个深色图像。我该如何解决这个问题?
  • @ssnake 正如 Jongware 所说,删除 alpha。您的图像实际上没有 alpha,而是 RGB + 0-pad。
  • 不得不改变 samplesPerPixel = 4;到samplesPerPixel = 3; int[] bandOffsets = {2, 1, 0, 3}; // BGRA order to int[] bandOffsets = {2, 1, 0}; // BGR order ,构造函数 ComponentColorModel(...) 中的第一个 false 参数为 true 并且它起作用了!!
【解决方案2】:

使用 Matlab,您可以用 2 行代码转换所有类型的图像:

img=imread('example.CR2');
imwrite(img,'example.JPG');

【讨论】:

  • 这个问题是关于Java的,没有提到Matlab。
猜你喜欢
  • 2019-05-29
  • 1970-01-01
  • 2020-06-14
  • 2015-05-21
  • 2012-01-25
  • 2012-06-01
  • 1970-01-01
  • 2018-12-15
  • 2012-12-26
相关资源
最近更新 更多