来自二维数组的 C++ 16 位灰度渐变图像

标签 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

最佳答案

您不能在 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 header 都未被解析,因此编译速度更快 - 但这意味着您无法显示程序中的图像,因此这意味着您 “head-少”
  • -Dcimg_use_png 表示您可以使用 libpng 读取/写入 PNG 图像,而不需要安装 ImageMagick
  • -lz -lpng 表示生成的代码与 PNG 和 ZLIB 库链接。

关于来自二维数组的 C++ 16 位灰度渐变图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51434899/

相关文章:

Android 垃圾收集运行异常

java - 我必须使用哪些类和方法才能从 C++ 调用 Java?

c++ - 为什么 int count 在进入循环时从 1 跳到 4? C++

image - 在成功的 TeamCity 构建上创建 Docker 镜像

Android Bitmpafun 在 BitmapFactory.decodeFileDescriptor 崩溃

java - 直接在指定位图下绘制文本

c++ - 如何实现这个练习(动态数组)?

c++ - 在 vector 中使用删除或调整大小哪个更快?

html - 在容器内制作具有不同高度比例的图像

无需重新加载的 Jquery 克隆图像