字节数组为8位真彩色图像

时间:2016-04-18 22:36:29

标签: java image colors sprite

我试图从旧的PC游戏中撕掉一些精灵。我发现了这些精灵并将它们撕成灰度的单个文件。现在我想弄清楚如何着色它们。可执行文件或其数据文件中似乎没有任何调色板数据 - 这与游戏所需的颜色深度(256色)相结合,使我相信每个字节实际上是8位真彩色值。

假设我有一个(在这种情况下缩短)数组,看起来像这样:

12 11 12 11
0A 13 12 11
13 12 11 0A
12 11 13 13

类似于我用于编写图像的示例代码如下所示:

DataInputStream dis = new DataInputStream(new FileInputStream("GAME.EXE"));

dis.skipBytes(bytesToImage);

BufferedImage bufferedImage = new BufferedImage(columns, rows, BufferedImage.TYPE_BYTE_INDEXED);

for (int i = 0; i < rows; i++) {
    for (int j = 0; j < columns; j++) {
        byte pixel = dis.readByte();

        System.out.print(toHexString(pixel));

        //For now, greyscale everything.
        int value = pixel << 16 | pixel << 8 | pixel;

        bufferedImage.setRGB(j, i, value);
    }

    System.out.print(System.getProperty("line.separator"));
}

ImageIO.write(bufferedImage, "PNG", new File("test.png"));

我已经将传入构造函数的imageType和手动传入ColorModel弄乱了,但似乎都没有做任何有用的事情。对像素执行二进制AND和一些位移大多只是将图像设置为深红色。

在这种情况下,如何将每个像素设置为正确的truecolor值?

1 个答案:

答案 0 :(得分:0)

8位真彩色意味着位7到5包含红色,位4到2包含绿色,位1和0包含蓝色。 (即RRRGGGBB)您需要将这些转换为24位真彩色模型中的高位。

使用24位RGB颜色的颜色模型(如TYPE_INT_RGB或TYPE_INT_ARGB),并从8位值中获取24位像素值:

int pixel24 = 
    ((pixel & (128+64+32)) << (16+5-5)) |
    ((pixel & (16+8+4))    << (8+5-2))  |
    ((pixel & (2+1))       << 6);

换句话说:

int pixel24 = 
    ((pixel & 224) << 16) | ((pixel & 28) << 11) | ((pixel & 3) << 6);

或者

int pixel24 = 
    ((pixel & 0xE0) << 16) | ((pixel & 0x1C) << 11) | ((pixel & 0x03) << 6);