作为上下文,我正在构建一个需要相对极端细节的地形程序。我不希望文件很小,也不需要在监视器上正式查看,它们只需要具有非常高的分辨率。
我知道大多数图像格式都限制为 8 bpp,这是由于显示器(以合理的价格)和人类感知的标准限制。然而,2⁸ 只是 256 个可能的值,这会在重建位移中引起平台伪影。2¹⁶ 在 65,536 个可能的值上可能足够接近,我已经实现了。
我正在使用 FreeImage 和 DLang 来构建数据,目前在 Linux Mint 机器上。
然而,当我继续使用 2³² 时,我的软件支持似乎逐渐淡化。我尝试了这种形式的 TIFF,似乎没有任何东西能够解释它,要么显示完全(或大部分)透明的图像(记住我不希望任何显示器真正支持 2³² 的通道阴影),要么抱怨被无法解码 RGB 数据。我想这是因为它被假定为 RGB 或 RGBA 图像。
FreeImage 对于大多数用途都有很好的记录,但我现在想知道,我可以导出的最高精度单通道格式是什么,我该怎么做?谁能提供一个例子?在任何典型的和非家庭滚动的图像格式中,我真的被限制为 16 位吗?我知道这对于医学成像来说已经足够高了,但我敢肯定我不是第一个尝试瞄准更高目标的人,我们科学类型的人对我们的精度水平可能非常雄心勃勃……</p>
我在代码中犯了明显的错误吗?为了这种精度,我还应该尝试其他什么方法吗?
这是我的代码。
有效的 16 位 TIFF
void writeGrayscaleMonochromeBitmap(const double width, const double height) {
FIBITMAP *bitmap = FreeImage_AllocateT(FIT_UINT16, cast(int)width, cast(int)height);
for(int y = 0; y < height; y++) {
ubyte *scanline = FreeImage_GetScanLine(bitmap, y);
for(int x = 0; x < width; x++) {
ushort v = cast(ushort)((x * 0xFFFF)/width);
ubyte[2] bytes = nativeToLittleEndian(cast(ushort)(x/width * 0xFFFF));
scanline[x * ushort.sizeof + 0] = bytes[0];
scanline[x * ushort.sizeof + 1] = bytes[1];
}
}
FreeImage_Save(FIF_TIFF, bitmap, "test.tif", TIFF_DEFAULT);
FreeImage_Unload(bitmap);
}
32 位 TIFF 并没有真正起作用
void writeGrayscaleMonochromeBitmap32(const double width, const double height) {
FIBITMAP *bitmap = FreeImage_AllocateT(FIT_UINT32, cast(int)width, cast(int)height);
writeln(width, ", ", height);
writeln("Width: ", FreeImage_GetWidth(bitmap));
for(int y = 0; y < height; y++) {
ubyte *scanline = FreeImage_GetScanLine(bitmap, y);
writeln(y, ": ", scanline);
for(int x = 0; x < width; x++) {
//writeln(x, " < ", width);
uint v = cast(uint)((x/width) * 0xFFFFFFFF);
writeln("V: ", v);
ubyte[4] bytes = nativeToLittleEndian(v);
scanline[x * uint.sizeof + 0] = bytes[0];
scanline[x * uint.sizeof + 1] = bytes[1];
scanline[x * uint.sizeof + 2] = bytes[2];
scanline[x * uint.sizeof + 3] = bytes[3];
}
}
FreeImage_Save(FIF_TIFF, bitmap, "test32.tif", TIFF_NONE);
FreeImage_Unload(bitmap);
}
感谢您的任何指示。