Sign in to follow this  
phi

write bmp

Recommended Posts

Hi, I'm new to imaging in code. I'm using C++ and am trying to create a bitmap using only STL and no other libraries. I've got a BMP header file, but I'm not sure how to write to a new bitmap file. At the moment, I've read in the bitmap header, and outputted it to a new file "nBitmap.bmp" and it creates a 200x200 file, like it should. However, if I try and open it in windows picture viewer, it says "drawing failed". How do I append pixel data to the end of the header part? I assume I use CHAR since it's 8 bytes, and the final bmp is 24 bits. Thanks

Share this post


Link to post
Share on other sites
Yeah, I would use unsigned char's, if it's a 24bit bitmap you'll need three for each pixel.

An important thing to remember when saving the pixel data into the file, is that the rows must be padded to multiples of four bytes. If you have a row of say, 17 pixels in a 24bit image, that's 17 * 3 = 51 bytes, which means you'd have to add an extra byte to pad it to a multiple of four (52). Just use zero values to pad the rows, though I'm not really sure if it matters or not.

Depending on the bit depth and some other things, you might also need to add the RGB quad or colour ramp headers before the pixel data, but for 24bit the file and info headers will probably suffice.

Share this post


Link to post
Share on other sites
As knowyourrole pointed out, rows must be padded if the width dimension is not divisible by four.

For 8-bit images, you need to store a palette (4 bytes per color, BGRx) after the header but before the pixel data. The palette is byte aligned too, hence the dummy byte x.

By the way, don't test images with MS Paint, it has a bug on 8-bit images (since Windows 3.11!) where the number of palette colors in the header is zero.

Share this post


Link to post
Share on other sites
Thanks for the replies. I found that site before, but I'm confused as to how to actually implement the theory. If, for example, I do this:
pixel[x][y] = 10;
How would I access the RGB channels individually and how would I assign the pixel[x][y] value to the actual image instead of just placing it in an array called pixel?
Sorry if these are silly questions, but I'm new to this and it's quite confusing.

Share this post


Link to post
Share on other sites
Assuming 24-bit images, have a struct:

struct rgb
{
char b;
char g;
char r;
};

// increase "width" if padding is needed
rgb *pixels = new rgb[width*height]; // your image data


Access pixels like this:

// if your coordinates are x,y
int i = x+(y*width);

// or alternatively:
int i = x+(((height-1)-y)*width); // if you have a vertically flipped image

// set pixel color
pixel[i].r = red;
pixel[i].g = green;
pixel[i].b = blue;

Share this post


Link to post
Share on other sites
Hi, thanks for the reply. This is what I've got so far. It compiles, but produces a bitmap. However, the image on the bitmap is just vertical lines of purple and green. (Maybe the red and blue are too close that they look purple)? I'm trying to make it all blue. What have I done wrong?


#include <fstream>
#include <iostream>



using namespace std;


struct rgb {
char b;
char g;
char r;


};

// increase "width" if padding is needed
rgb *pixel = new rgb[700 * 700]; // your image data



// or alternatively:
//int i = x+(((700-1)-y)*700); // if you have a vertically flipped image

int main()
{
char fileName[54];
char buffer[255];


ofstream fout("bitmap.bmp", ios::app);

ifstream fin("bmpH.hdr");
char ch;

while(fin.get(ch)) //write out the header to the file
{
fout << ch;
}


for (int j=(699); j >=0 ; j--){
for (int l=0; l<700; l++){

// if your coordinates are x,y
int i = l+(j*700);

pixel[i].b = 255;
pixel[i].g = 0;
pixel[i].r = 0;

fout << pixel;


}
}









fin.close();




return 0;


}

Share this post


Link to post
Share on other sites
I've fixed the problem. Turns out I didn't delete the old bitmap file, so it appended to it rather than overwriting it. However, I can't seem to be able to access individual pixels. If I do:

pixel[SPECIFIC PIXEL NUMBER].b = 0x00;
pixel[SPECIFIC PIXEL NUMBER].g = 0x00;
pixel[SPECIFIC PIXEL NUMBER].r = 0xFF;

it doesn't do anything. How would I go about accessing individual pixels?
Thanks for the help :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this