来自二维数组的 C++ 16 位灰度渐变图像
C++ 16 bit grayscale gradient image from 2D array
我目前正在尝试构建 16 位灰度 "gradient" 图像,但我的输出看起来很奇怪,所以我显然没有正确理解这一点。我希望有人能对我的问题有所了解。我认为我写的 "bitmap" 是错误的?但我不确定。
#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;
}
当前输出:
您遇到了 8 位与 16 位的问题。您正在编写 16 位值,但库将它们解释为 8 位。这就是对可见的深色垂直条的解释。它在每个值的低字节和高字节之间交替,将它们视为两个单独的像素值。
而造成"gradient venetian blind"效果的原因又是因为只考虑了低字节。这将在 12 步中从 0 循环到 240,然后在下一步中溢出回到 5,依此类推。
我不是 cimg_library
专家,但一个好的起点可能是用 uint16_t
替换 uint8_t
并看看有什么效果。
您不能在 BMP 中存储 16 位灰度样本...参见 Wikipedia。
BMP 中的每像素 16 位选项允许您存储 4 位红色、4 位绿色、4 位蓝色和 4 位 alpha,但不能存储 16 位灰度。
24 位格式允许您存储 1 个字节的红色、1 个字节的绿色和 1 个字节的蓝色,但不能存储 16 位灰度。
32 位 BMP 允许您存储 24 位 BMP 加 alpha。
您将需要使用 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 headers 都没有被解析,因此编译速度更快 - 但这意味着您无法显示程序中的图像,所以这意味着您 "head-less"
-Dcimg_use_png
意味着您可以使用 libpng
read/write PNG 图像而不需要安装 ImageMagick
-lz -lpng
表示生成的代码与 PNG 和 ZLIB 库链接。
我目前正在尝试构建 16 位灰度 "gradient" 图像,但我的输出看起来很奇怪,所以我显然没有正确理解这一点。我希望有人能对我的问题有所了解。我认为我写的 "bitmap" 是错误的?但我不确定。
#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;
}
当前输出:
您遇到了 8 位与 16 位的问题。您正在编写 16 位值,但库将它们解释为 8 位。这就是对可见的深色垂直条的解释。它在每个值的低字节和高字节之间交替,将它们视为两个单独的像素值。
而造成"gradient venetian blind"效果的原因又是因为只考虑了低字节。这将在 12 步中从 0 循环到 240,然后在下一步中溢出回到 5,依此类推。
我不是 cimg_library
专家,但一个好的起点可能是用 uint16_t
替换 uint8_t
并看看有什么效果。
您不能在 BMP 中存储 16 位灰度样本...参见 Wikipedia。
BMP 中的每像素 16 位选项允许您存储 4 位红色、4 位绿色、4 位蓝色和 4 位 alpha,但不能存储 16 位灰度。
24 位格式允许您存储 1 个字节的红色、1 个字节的绿色和 1 个字节的蓝色,但不能存储 16 位灰度。
32 位 BMP 允许您存储 24 位 BMP 加 alpha。
您将需要使用 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 headers 都没有被解析,因此编译速度更快 - 但这意味着您无法显示程序中的图像,所以这意味着您 "head-less"-Dcimg_use_png
意味着您可以使用libpng
read/write PNG 图像而不需要安装 ImageMagick-lz -lpng
表示生成的代码与 PNG 和 ZLIB 库链接。