В настоящее время я пытаюсь создать 16-битное градиентное изображение в градациях серого, но мои результаты выглядят странно, поэтому я не совсем правильно понимаю. Я надеялся, что кто-нибудь сможет пролить немного знаний на мою проблему. Я думаю, что «растровое изображение» я пишу неправильно? Но я не уверен.
#include "CImg.h"using namespace std;
unsigned short buffer[1250][1250];
void fill_buffer()
{
unsigned short temp_data = 0;
for (int i =0;i < 1250; i++)
{
for (int j =0 ;j < 1250;j++)
{
buffer[i][j] = temp_data;
}
temp_data += 20;
}
}
int main()
{
fill_buffer();
auto hold_arr = (uint8_t *)&buffer[0][0];
cimg_library::CImg<uint8_t> img(hold_arr, 1250, 1250);
img.save_bmp("test.bmp");
return 0;
}
Токовый выход:
Вы не можете хранить 16-битные образцы в градациях серого в BMP … см. Википедия.
Опция 16 бит на пиксель в BMP позволяет хранить 4 бита красного, 4 бита зеленого, 4 бита синего и 4 бита альфа, но не 16-битного оттенка серого.
24-битный формат позволяет хранить 1 байт для красного, 1 байт для зеленого и один байт для синего, но не 16-битную шкалу серого.
32-битный BMP позволяет хранить 24-битный BMP плюс альфа.
Вам нужно будет использовать PNG
или NetPBM Формат PGM или TIFF
формат. PGM
формат отличный, потому что CImg
можно написать, что без каких-либо библиотек, и вы всегда можете использовать ImageMagick преобразовать это во что-нибудь еще, например:
convert image.pgm image.png
или же
convert image.pgm image.jpg
Это работает:
#define cimg_use_png
#define cimg_display 0
#include "CImg.h"
using namespace cimg_library;
using namespace std;
unsigned short buffer[1250][1250];
void fill_buffer()
{
unsigned short temp_data = 0;
for (int i =0;i < 1250; i++)
{
for (int j =0 ;j < 1250;j++)
{
buffer[i][j] = temp_data;
}
temp_data += 65535/1250;
}
}
int main()
{
fill_buffer();
auto hold_arr = (unsigned short*)&buffer[0][0];
cimg_library::CImg<unsigned short> img(hold_arr, 1250, 1250);
img.save_png("test.png");
return 0;
}
Обратите внимание, что при запросе CImg
чтобы написать файл PNG, вам нужно будет использовать такую команду (с libpng
а также zlib
) Скомпилировать:
g++-7 -std=c++11 -O3 -march=native -Dcimg_display=0 -Dcimg_use_png -L /usr/local/lib -lm -lpthread -lpng -lz -o "main" "main.cpp"
Просто для объяснения:
-std=c++11
просто устанавливает стандарт C ++-O3 -march=native
только для ускорения вещей и строго не требуется-Dcimg_display=0
означает, что все заголовки X11 не анализируются, поэтому компиляция происходит быстрее — однако это означает, что вы не можете отображать изображения из вашей программы, а значит, вы «без головы»-Dcimg_use_png
означает, что вы можете читать / записывать изображения в формате PNG, используя libpng
вместо того, чтобы устанавливать ImageMagick-lz -lpng
означает, что полученный код связан с библиотеками PNG и ZLIB.У вас 8-битная или 16-битная проблема. Вы пишете 16-битные значения, но библиотека интерпретирует их как 8-битные. Это объяснение темных вертикальных полос, которые видны. Он чередуется между младшим и старшим байтами каждого значения, рассматривая их как два отдельных значения пикселей.
И причина «градиентного венецианского слепого» эффекта опять-таки связана только с учетом младшего байта. Это будет цикл от 0 до 240 в 12 шагов, а затем переполнится до 5 на следующем шаге, и так далее.
я — нет cimg_library
эксперт, но хорошей отправной точкой может быть замена uint8_t
с uint16_t
и посмотрим, какой эффект это имеет.