我试图将 aBufferedImage
从byte[]
32 位 RGBA 转换为 24 位 RGB。根据这个答案,从图像中获取的最快方法byte[]
是:
byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
所以我迭代所有字节,假设它们的顺序是 RGBA,并且对于每 4 个字节,我将前 3 个写入输出 byte[](即忽略 alpha 值)。
当从 Eclipse 运行并且字节被正确转换时,这工作正常。但是,当我从命令行运行相同的程序时,会以相反的字节顺序返回相同的字节!
我用于测试的测试图像是 5x5 黑色图像,其中只有左上角的 RGBA 颜色不同[aa cc ee ff]
:
为了方便起见,还有一个放大版本:
我的文件夹结构是:
- src/
- test.png
- test/
- TestBufferedImage.java
SSCCE如下:
package test;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
public class TestBufferedImage {
private static void log(String s) {
System.out.println(s);
}
private static String toByteString(byte b) {
// Perform a bitwise AND for convenience while printing.
// Otherwise Integer.toHexString() interprets values as integers and a negative byte 0xFF will be printed as "ffffffff"
return Integer.toHexString(b & 0xFF);
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
InputStream stream = TestBufferedImage.class.getClassLoader().getResourceAsStream("test.png");
BufferedImage image = ImageIO.read(stream);
stream.close();
log("Image loaded succesfully, width=" + image.getWidth() + " height=" + image.getHeight());
log("Converting from 32-bit to 24-bit...");
DataBufferByte buffer = (DataBufferByte)image.getRaster().getDataBuffer();
byte[] input = buffer.getData();
byte[] output = convertTo24Bit(input);
log("Converted total of " + input.length + " bytes to " + output.length + " bytes");
}
private static byte[] convertTo24Bit(byte[] input) {
int dataLength = input.length;
byte[] convertedData = new byte[ dataLength * 3 / 4 ];
for (int i = 0, j = 0; i < dataLength; i+=4, j+=3) {
convertIntByteToByte(input, i, convertedData, j);
}
return convertedData;
}
private static void convertIntByteToByte(byte[] src, int srcIndex, byte[] out, int outIndex) {
byte r = src[srcIndex];
byte g = src[srcIndex+1];
byte b = src[srcIndex+2];
byte a = src[srcIndex+3];
out[outIndex] = r;
out[outIndex+1] = g;
out[outIndex+2] = b;
log("i=" + srcIndex
+ " Converting [" + toByteString(r) + ", " + toByteString(g)
+ ", " + toByteString(b) + ", " + toByteString(a) + "] --> ["
+ toByteString(out[outIndex]) + ", " + toByteString(out[outIndex+1])
+ ", " + toByteString(out[outIndex+2]) + "]"
);
}
}
从 Eclipse 运行时的输出(版本:Juno Service Release 2 Build id:20130225-0426):
Image loaded succesfully, width=5 height=5
Converting from 32-bit to 24-bit...
i=0 Converting [aa, cc, ee, ff] --> [aa, cc, ee] // <-- Bytes have the correct order
i=4 Converting [0, 0, 0, ff] --> [0, 0, 0]
i=8 Converting [0, 0, 0, ff] --> [0, 0, 0]
.....
i=96 Converting [0, 0, 0, ff] --> [0, 0, 0]
Converted total of 100 bytes to 75 bytes
从命令行(Windows Vista)运行时的输出java test.TestBufferedImage
:
Image loaded succesfully, width=5 height=5
Converting from 32-bit to 24-bit...
i=0 Converting [ff, ee, cc, aa] --> [ff, ee, cc] // <-- Bytes are returned with a different byte order!
i=4 Converting [ff, 0, 0, 0] --> [ff, 0, 0]
i=8 Converting [ff, 0, 0, 0] --> [ff, 0, 0]
.....
i=96 Converting [ff, 0, 0, 0] --> [ff, 0, 0]
Converted total of 100 bytes to 75 bytes
那么有没有人遇到过类似的问题和/或可以解释实际发生了什么?为什么从 Eclipse 内部运行时字节顺序不同?