Skip to content

Instantly share code, notes, and snippets.

@HappyCerberus
Created October 23, 2012 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HappyCerberus/3940039 to your computer and use it in GitHub Desktop.
Save HappyCerberus/3940039 to your computer and use it in GitHub Desktop.
BMP image format writing helper
#include <vector>
#include <cstdint>
#include <iostream>
using namespace std;
class BitmapWriter
{
public:
struct RGB { unsigned char red; unsigned char green; unsigned char blue;
RGB(double r, double g, double b) : red((unsigned char)(r*256)), green((unsigned char)(g*256)), blue((unsigned char)(b*256)) {}
};
friend ostream& operator << (ostream& s, const BitmapWriter& b)
{
char byte;
uint16_t word;
uint32_t dword;
#define raw_write(var,value) var = value; s.write(reinterpret_cast<char*>(&var),sizeof(var));
// HEADER
raw_write(byte,'B');
raw_write(byte,'M');
raw_write(dword,b.p_data.size()*3);
raw_write(word,0);
raw_write(word,0);
raw_write(dword,0x36);
// INFO
raw_write(dword,sizeof(dword)*9+sizeof(word)*2);
raw_write(dword,b.p_x);
raw_write(dword,b.p_y);
raw_write(word,1);
raw_write(word,24);
raw_write(dword,0);
raw_write(dword,0);
raw_write(dword,0x0ec4);
raw_write(dword,0x0ec4);
raw_write(dword,0);
raw_write(dword,0);
// DATA
size_t padding = (4-(b.p_x*3%4))%4;
for (size_t i = 0; i < b.p_y; i++)
{
for (size_t j = 0; j < b.p_x; j++)
{
raw_write(byte,b.p_data[i*b.p_x+j].blue);
raw_write(byte,b.p_data[i*b.p_x+j].green);
raw_write(byte,b.p_data[i*b.p_x+j].red);
}
for (size_t j = 0; j < padding; j++)
{
raw_write(byte,0);
}
}
#undef raw_write
return s;
}
BitmapWriter(const vector<RGB>& data, size_t x, size_t y) : p_data(data), p_x(x), p_y(y) {}
private:
const vector<RGB>& p_data;
size_t p_x;
size_t p_y;
};
/* Conversion routine from HSV color space to RGB */
BitmapWriter::RGB hsv2rgb(double h, double s, double v)
{
if (s <= 0)
{
if (std::isnan(h))
{
return BitmapWriter::RGB(v,v,v);
}
else
{
return BitmapWriter::RGB(0,0,0);
}
}
else
{
double hh = h;
if (hh >= 360) hh = 0;
hh /= 60;
short i = (short)hh;
double ff = hh - i;
double p = v * (1.0-s);
double q = v * (1.0 - (s * ff));
double t = v * (1.0 - (s * (1.0 - ff)));
switch (i)
{
case 0:
return BitmapWriter::RGB(v,t,p);
case 1:
return BitmapWriter::RGB(q,v,p);
case 2:
return BitmapWriter::RGB(p,v,t);
case 3:
return BitmapWriter::RGB(p,q,v);
case 4:
return BitmapWriter::RGB(t,p,v);
case 5:
default:
return BitmapWriter::RGB(v,p,q);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment