如何在java中从像素字节数组制作bmp图像

问题描述 投票:0回答:2

我有一个字节数组,其中包含 .bmp 文件中的像素值。它是通过这样做生成的:

BufferedImage readImage = ImageIO.read(new File(fileName));
byte imageData[] = ((DataBufferByte)readImage.getData().getDataBuffer()).getData();

现在我需要重新创建 .bmp 图像。我尝试制作 BufferedImage 并通过调用

setPixels
方法设置 WritableRaster 的像素。但我必须提供一个 int[]、float[] 或 double[] 数组。也许我需要将字节数组转换为其中之一。但我不知道该怎么做。我也尝试过
setDataElements
方法。但我也不知道如何使用这个方法。

任何人都可以解释如何从字节数组创建 bmp 图像吗?

编辑:@Perception

这就是我到目前为止所做的:

private byte[] getPixelArrayToBmpByteArray(byte[] pixelData, int width, int height, int depth) throws Exception{
    int[] pixels = byteToInt(pixelData);

    BufferedImage image = null;
    if(depth == 8) {
        image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    }
    else if(depth == 24){
        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    }
    
    WritableRaster raster = (WritableRaster) image.getData();
    raster.setPixels(0, 0, width, height, pixels);
    image.setData(raster);
    return getBufferedImageToBmpByteArray(image);
}

private byte[] getBufferedImageToBmpByteArray(BufferedImage image) {
    byte[] imageData = null;
    try {
        ByteArrayOutputStream bas = new ByteArrayOutputStream();
        ImageIO.write(image, "bmp", bas);
        imageData = bas.toByteArray();
        bas.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return imageData;
}

private int[] byteToInt(byte[] data) {
    int[] ints = new int[data.length];
    for (int i = 0; i < data.length; i++) {
        ints[i] = (int) data[i] & 0xff;
    }
    return ints;
} 

问题是,这对于灰色图像来说效果很好,但对于彩色图像来说,颜色不正确。我认为这与

byteToInt
方法有关。如果有人知道如何改进它或者有一个新的更简单的解决方案,我们将不胜感激您的帮助..:)

java raster pixel bufferedimage
2个回答
2
投票

您需要将三个字节打包到您创建的每个整数中。根据缓冲图像的格式,这将是 0xRRGGBB。

byteToInt 必须像这样消耗三个字节:

private int[] byteToInt(byte[] data) {
    int[] ints = new int[data.length / 3];

    int byteIdx = 0;
    for (int pixel = 0; pixel < ints.length) {
        int rByte = (int) pixels[byteIdx++] & 0xFF;
        int gByte = (int) pixels[byteIdx++] & 0xFF;
        int bByte = (int) pixels[byteIdx++] & 0xFF;
        int rgb = (rByte << 16) | (gByte << 8) | bByte
        ints[pixel] = rgb;
    }
}

您还可以使用 ByteBuffer.wrap(arr, offset, length).toInt()


0
投票

仅拥有一个字节数组是不够的。您还需要构造一个标头(如果您正在读取原始格式,例如在 DICOM 文件内)。

© www.soinside.com 2019 - 2024. All rights reserved.