I am currently working on a project that needs to output generated images. I have decided to the use greyscale netbpm format due to its simplicity. One of these images is a heightmap. My code to export it is as follows:
#include <array>
#include <fstream>
#include <iostream>
int main(){
constexpr unsigned LENGTH = 4;
std::array<double, LENGTH*LENGTH> m_data = {
0, 0, 0, 0,
0, 1, 1, 0,
0, 1, 1, 0,
0, 0, 0, 0
};
std::ofstream fout;
fout.exceptions(std::ios::badbit | std::ios::failbit);
fout.open("test.pgm", std::ios::binary);
fout << "P5 " << LENGTH << " " << LENGTH << "\n256\n";
for(unsigned i=0;i<LENGTH*LENGTH;++i){
unsigned char brightness = m_data[i]*255;
std::cout << m_data[i] << std::endl;
fout.write(reinterpret_cast<char*>(&brightness), sizeof(unsigned char));
}
return 0;
}
This code looks correct to me, after reading the specification for the netbpm format on Wikipedia. Yet, when I attempt to open this image in either Gimp or Clion there are various errors:
The file is saved with a pgm
extension. What is wrong with my code?
Try writing the NetPBM header like this:
fout << "P5\n" << LENGTH << " " << LENGTH << "\n255\n";
The reason is that most image readers check the MAXVAL and if it is 255 or less, they assume 8-bits per pixel. If MAXVAL exceeds 255, they assume 16-bits per pixel, so they will complain that your file is too short (as it doesn't provide 2 bytes per pixel).