来自2D阵列的C ++ 16位灰度渐变图像

时间:2018-07-20 04:04:14

标签: c++ image bitmap 16-bit cimg

我目前正在尝试构建一个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;
}

电流输出: Current Output

2 个答案:

答案 0 :(得分:3)

您遇到了8位和16位的问题。您正在编写16位值,但是库将它们解释为8位。这就是可见的深色竖线的解释。它在每个值的低字节和高字节之间交替,将它们视为两个单独的像素值。

“梯度百叶窗”效应的原因再次是由于仅考虑了低字节。它将以12个步骤从0循环到240,然后在下一步中溢出回到5,依此类推。

我不是cimg_library专家,但是一个不错的起点可能是用uint8_t代替uint16_t,看看效果如何。

答案 1 :(得分:3)

您无法在BMP中存储16位灰度样本...请参见Wikipedia

BMP中的每像素16位选项允许您存储4位红色,4位绿色,4位蓝色和4位alpha,但不存储16位灰度。

24位格式允许您存储1字节的红色,1字节的绿色和1字节的蓝色,但不能存储16位的灰度。

32位BMP允许您存储24位BMP加alpha。

您将需要使用PNGNetPBM 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;
}

enter image description here

请注意,当要求CImg编写PNG文件时,您将需要使用以下命令(带有libpngzlib)进行编译:

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意味着您可以使用libpng读取/写入PNG图像,而不需要安装ImageMagick
  • -lz -lpng意味着生成的代码已与PNG和ZLIB库链接。