В качестве контекста я работаю над созданием топографической программы, которая требует относительно экстремальных деталей. Я не ожидаю, что файлы будут маленькими, и их формально не нужно просматривать на мониторе, им просто нужно иметь очень высокое разрешение.
Я знаю, что большинство форматов изображений ограничены 8 битами на дюйм,из-за стандартных ограничений на мониторы (по разумной цене) и на восприятие человеком. Тем не менее, 2⁸ - это всего лишь 256 возможных значений, что вызывает искажения плато при восстановленном смещении. 2¹⁶ может быть достаточно близко при 65 536 возможных значениях, которых я достиг.
Я использую FreeImage и DLang для построения данных, в настоящее время на машине Linux Mint.
Однако, когда япошел до 2³², поддержка программного обеспечения, казалось, исчезла на мне. Я попробовал TIFF этой формы, и ничто, казалось, не могло его интерпретировать, либо показывать полностью (или в основном) прозрачное изображение (помня, что я не ожидал, что какой-либо монитор действительно поддерживает 2,32 оттенка канала), либо жаловался на то, чтоневозможно декодировать данные RGB. Я полагаю, что это потому, что предполагалось, что это изображение RGB или RGBA.
FreeImage достаточно хорошо документировано для большинства целей, но сейчас я задаюсь вопросом, какой формат записи с максимальной точностью я могуэкспорт, а как бы я это сделал? Кто-нибудь может привести пример? Действительно ли я ограничен в любом типичном и нестандартном формате изображения 16-битным? Я знаю, что это достаточно высоко для, скажем, медицинской визуализации, но я уверен, что я не первый, кто пытается стремиться к более высокому уровню, и мы, любители науки, можем быть довольно амбициозными в отношении нашего уровня точности…
Я сделал грубую ошибку в своем коде? Есть ли что-то еще, что я должен попробовать вместо этого для точности такого рода?
Вот мой код.
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);
}
Спасибо за любые указатели.