我正在使用 PNGDecoder 解码高度图 png。然而,当我打印控制台中返回的值时,我发现一些 rgb 值返回为负数
-128, -128, -128, -1
-128, -128, -128, -1
-128, -128, -128, -1
-124, -124, -124, -1
-119, -119, -119, -1
-118, -118, -118, -1
我用来解码然后读取的代码如下
public static ByteBuffer decodeImage(String path) throws IOException {
InputStream stream = new FileInputStream(path);
PNGDecoder decoder = new PNGDecoder(stream);
ByteBuffer decodedImageData = ByteBuffer.allocateDirect(4 * decoder.getWidth() * decoder.getHeight());
decoder.decodeFlipped(decodedImageData, decoder.getWidth() * 4, PNGDecoder.Format.RGBA);
decodedImageData.flip();
return decodedImageData;
}
private void applyHeightMap (String heightMapPath) throws IOException {
float vertices[] = plane.getVertices();
ByteBuffer buffer = Texture.decodeImage(heightMapPath);
for (int i = 0; i < 2624 * 1756; i++) {
byte r = buffer.get();
byte g = buffer.get();
byte b = buffer.get();
byte a = buffer.get();
if(r < 0 || b < 0 || g < 0) {
System.out.println(r + ", " + g + ", " + b+", "+a);
}
}
}
不确定为什么负值很少,以及为什么 alpha 通道读为 -1
我使用的图像是https://learnopengl.com/img/guest/2021/tessellation/height_map/iceland_heightmap.png
Java 的
byte
类型是有符号的8 位类型。这意味着 8 位表示从 -128 到 127 的值。另一方面,图像以每个通道的无符号 8 位类型存储,表示 [0, 255]。当您查看打印的值 -128、-128、-128、-1 时,您实际上拥有
10000000
-128 和11111111
-1 的二进制数据。当将其转换为无符号 8 位时,它10000000
= 128 和11111111
= 255。Java 没有无符号类型,但我认为 lwjgl 在将图像传递给 OpenGL 时只会关心二进制数据,而不是数字表示。
如果要打印这些值,则需要将字节转换为足够大的数据类型以表示 [0,255] 范围,例如转换为 int。类似以下代码应该可以打印正确的值:
转换取自https://mkyong.com/java/java-convert-bytes-to-unsigned-bytes/#:~:text=In%20Java%2C%20byte%20is%20an,bytes%20(0%20to%20255)。