0
votes

I have a byte array, where each byte describes one pixel (256 colors). Here is bitmask that I use: 0xRRRGGGBB So there are 3 bits for R and G components and 2 bits for B component. How can I construct BufferedImage from that array assuming that I know width and height of the image?

1
Why do you need three bits for red and green? The usual bitmask is "RRGGBBAA" (or "AARRGGBB") where "A" stands for alpha.Tom
I don't need alpha component for my purpose. I construct color model: DirectColorModel model = new DirectColorModel(8, 0b00000000000000000000000011100000, 0b00000000000000000000000000011100, 0b00000000000000000000000000000011) and buffer: DataBufferByte buffer = new DataBufferByte(data, data.length) but then I don't know how to construct rasterddms
And how would I construct BufferedImage assuming that I had RRGGBBAA mask?ddms
You could simply construct a matching palette and use IndexedColorModelDurandal

1 Answers

3
votes

First, we must create a data buffer with your data
DataBufferByte buffer = new DataBufferByte(data, data.length);

Next, we need to declare "bandMasks" so the raster can understand your format
int[] bandMasks = {0b11100000, 0b00011100, 0b00000011};

Now, we can create the raster
WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, bandMasks, null); (FYI, width is specified twice because it is the scansize)

Now we can create the image with the buffer, raster and Color Model
BufferedImage image = new BufferedImage(new DirectColorModel(8, 0b11100000, 0b00011100, 0b00000011), raster, false, null);
Also, you can trim off the proceeding 0's in binary literals because those bits will be 0 by default (0b00000011 is the same as 0b11 or (in decimal) 00029 is the same as 29) you don't need to specify all 32 bits in an integer

I verified the previous code works using this entire segment:

    byte[] data = new byte[]{
        (byte) 0b00000011/*Blue*/, (byte) 0b11100011/*Purple*/,
        (byte) 0b11100011/*Purple*/, (byte) 0b11111111/*White*/};//This is the "image"

    int width = 2, height = 2;

    DataBufferByte buffer = new DataBufferByte(data, data.length);
    int[] bandMasks = {0b11100000, 0b00011100, 0b00000011};

    WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, bandMasks, null);

    BufferedImage image = new BufferedImage(new DirectColorModel(8, 0b11100000, 0b00011100, 0b00000011), raster, false, null);

    JFrame frame = new JFrame("Test");
    Canvas c = new Canvas();
    frame.add(c);
    frame.setSize(1440, 810);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    while (true) {
        Graphics g = c.getGraphics();
        g.drawImage(image, 0, 0, image.getWidth() * 40, image.getHeight() * 40, null);
    }

I hope this helps!