C++: .bmp to byte array in a file
Asked Answered
W

2

2

Yes i have been through the other questions that are related to this, but i found them not much help. They were some help but i am still a bit confused. So here what what i need to do:

We have a 132x65 screen. I have a 132x65 .bmp. I want to go through the .bmp and separate it into little 1x8 columns to get the binary of that 32-bit column. Then do that 132 times across, and do that 9 times down. Anything that is not white should be counted as a bit. example:

If the top left pixel of the picture is any color that is not white and the 7 pixels below that are white then that would be the first element of the array, the hex of that number, so the array would look like this: array [] = { 0x01 } and then it would continue to fill through those 132 columns and then do it again for 9 "sections" of rows. And the file result would be ONLY that array in a separate file.

I understand the header format for this, i have read the wiki article on .bmp file formats, my main problem is i don't really know how to interact with the .bmp when i actually want it to go inside and interact with each pixel from the image. I really dont need the whole thing, but maybe just an example of grabbing each pixel from the .bmp and outputting the color of the pixel into a file or something. My c++ is a little rusty (been doing java and javscript lately).

Wolverhampton answered 12/4, 2012 at 13:25 Comment(3)
Have you picked a BMP library yet?Wherefore
No, i am willing to use any of them. I have looked through some of them but not really sure which is best/easiest/quickest for something like this.Wolverhampton
I have mainly tried using CImage class. My problem is i really dont know how to interact with the .bmp file. I really just need an example to work off of someone maybe just as simple as going onto a .bmp file and setting a pixel color or something. Like i said, it has been a while since i have done any c++ so i feel like i am just confusing myself when i try to interact with the .bmp file.Wolverhampton
H
5

If you want to read a known format BMP and don't care about how it's done (ie, internal-only thing) you can just take the BMP, ignore the header and use it as a pixel array. It is stored line by line starting at the bottom left. There are some detail snags for how it's packed but in my experience if you take a 32bpp image it can be completely ignored.

As a really simple example:

unsigned int *buffer;
void readfile() {
    FILE *f = fopen("file.bmp", "rb");
    buffer = new unsigned int[132*65];
    fseek(f, 54);
    fread(buffer, 132*65*4, 1, f);
    fclose(f);
}

unsigned int getpixel(int x, int y) {
    //assuming your x/y starts from top left, like I usually do
    return buffer[(64 - y) * 132 + x];
}
Hinton answered 12/4, 2012 at 14:28 Comment(6)
This is what i want! but they problem is i dont know how to do that syntactically... Like how do i interact with that first pixel?Wolverhampton
Added a code sample. The 54 is what I usually see in bmp files but it may be different for yours depending on optional headers. For clarity, open it with a hex editor and see for yourself.Hinton
you say "starts at the bottom left." and then in the example "starts from top left". Might need some clarification..Banuelos
Okay, so i got it figured out, i was reading out of bounds. silly me. But here is my issue, why does it always return zero? what is the value that i get from getpixel? is there anyway to have the value of getpixel return 0 if its white and 1 if its any other color?Wolverhampton
The value you get from it is the RGB value of a given pixel. Note that my example assumes 32-bit color BMPs of the correct aspect ratio with the expected header.Hinton
@Default I always assume that it's from the topleft so I try to do the top/bottom conversion as low as possible. In this case the (64 - y) does that.Hinton
C
1

I had the same problem, but by reading BMP file format description I wrote a function that reads a .BMP file and stores it into a array. Maybe this function can help you:

unsigned int PIC::BinToNum(char *b,int bytes)
{
    unsigned int tmpx = 0;
    unsigned int pw = 1;
    for(int i=0;i<bytes;i++)
    {
        tmpx += ((unsigned char)b[i]* pw);
        pw = pw * 256;
    }
    return tmpx;
}

int PIC::Open(const char *path)
{
    int pad = 0;
    unsigned int sof = 0;
    unsigned int tx = 0;
    char tmp[4] = {0,0,0,0};
    fstream file;
    file.open(path,ios::in);
    if(file.fail())
    {
        width=height=ColorBits=size=0;
        return -1;
    }
    else
    {
        file.seekg(0,ios::beg);
        file.read(tmp,2);
        if(!(tmp[0] == 66 && tmp[1] == 77))
        {
            width=height=ColorBits=size=0;
            return 0;
        }
        else
        {
            file.seekg(2,ios::beg); // 0x2 size
            file.read(tmp,4);
            size = BinToNum(tmp,4);
            file.seekg(18,ios::beg); // 0x12 width
            file.read(tmp,4);
            width = BinToNum(tmp,4);
            file.seekg(22,ios::beg); // 0x16 height
            file.read(tmp,4);
            height = BinToNum(tmp,4);
            file.seekg(28,ios::beg); // 0x1C Bits per Pixel
            file.read(tmp,2);
            ColorBits = BinToNum(tmp,2);
            file.seekg(10,ios::beg); // 0x0A start offset
            file.read(tmp,4);
            sof=BinToNum(tmp,4);
            file.seekg(34,ios::beg); // 0x22 Padding
            file.read(tmp,4);
            pad = BinToNum(tmp,4);
            pad = (int)(pad / height); // Compute Spacing in each row
            pad = pad - (width*ColorBits/8);

            // Initialize Matrix//
            matrix = new(unsigned int[height*width]);

            for(int h=height-1;h>=0;h--)
            {
                for(int w=0;w<=width-1;w++)
                {
                    file.seekg(sof,ios::beg);
                    file.read(tmp,(int)(ColorBits/8));
                    tx = BinToNum(tmp,(int)(ColorBits/8));
                    matrix[(h*width)+w] = tx;
                    sof+=(int)(ColorBits/8);
                }
                sof +=pad;
            }
        }
    }
    file.close();
    return 1;
}


Note:This functions is member of a class that i named it "PIC"...
Ceroplastic answered 26/3, 2013 at 12:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.