You cannot store 16-bit greyscale samples in a BMP... see Wikipedia.
The 16-bit per pixel option in a BMP allows you to store 4 bits of red, 4 bits of green, 4 bits of blue and 4 bits of alpha, but not 16-bits of greyscale.
The 24-bit format allows you to store 1 byte for red, 1 byte for green and one byte for blue, but not 16-bits of greyscale.
The 32-bit BMP allows you to store a 24-bit BMP plus alpha.
You will need to use PNG
, or a NetPBM PGM format, or TIFF
format. PGM
format is great because CImg
can write that without any libraries and you can always use ImageMagick to convert it to anything else, e.g.:
convert image.pgm image.png
or
convert image.pgm image.jpg
This works:
#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;
}

Note that when asking CImg
to write a PNG file, you will need to use a command like this (with libpng
and zlib
) to compile:
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"
Just by way of explanation:
-std=c++11
just sets the C++ standard
-O3 -march=native
is only to speed things up and is not strictly required
-Dcimg_display=0
means all the X11 headers are not parsed so compilation is quicker - however this means you can't display images from your program so it means you are "head-less"
-Dcimg_use_png
means you can read/write PNG images using libpng
rather than needing ImageMagick installed
-lz -lpng
means the resulting code gets linked with the PNG and ZLIB libraries.