Thread: Negating a bitmap image

  1. #1
    Registered User
    Join Date
    Oct 2011
    Location
    Ireland
    Posts
    30

    Negating a bitmap image

    Hello.

    I am hoping someone can give me some advice.

    I need to read in a file, a bitmap image, and make a negative of that file, saving it somewhere new.

    Now, reading in the file, and saving it are no problem. I just don't know how to head with the bitmap. I have a bitmap header file with Windows BMP file definitions for OpenGL.

    Do I need to take the following code, using it in my program to change each picel to a zero?

    Code:
    typedef struct                       /**** BMP file info structure ****/
        {
        unsigned int   biSize;           /* Size of info header */
        int            biWidth;          /* Width of image */
        int            biHeight;         /* Height of image */
        unsigned short biPlanes;         /* Number of color planes */
        unsigned short biBitCount;       /* Number of bits per pixel */
        unsigned int   biCompression;    /* Type of compression to use */
        unsigned int   biSizeImage;      /* Size of image data */
        int            biXPelsPerMeter;  /* X pixels per meter */
        int            biYPelsPerMeter;  /* Y pixels per meter */
        unsigned int   biClrUsed;        /* Number of colors used */
        unsigned int   biClrImportant;   /* Number of important colors */
        } BITMAPINFOHEADER;
    I guess to do that I need to read in an instance of BITMAPINFOHEADER?

    I really want to understand how to do this, but if someone could give me some advice, that would be fantastic.

    Thanks in advance.

    Seán

  2. #2
    Registered User NeonBlack's Avatar
    Join Date
    Nov 2007
    Posts
    431
    Read BMP file format - Wikipedia, the free encyclopedia . Bitmaps store pixels as either color table indices, or RGBA bytes, which makes working with them fairly straightforward.
    I copied it from the last program in which I passed a parameter, which would have been pre-1989 I guess. - esbo

  3. #3
    Registered User
    Join Date
    Oct 2011
    Location
    Ireland
    Posts
    30
    Hello, and thanks for the reply!

    Yes, I have to work with RGB values. From the information in the wikipedia page, I assume I was right in thinking that I need to work with the BITMAPINFOHEADER structure, manipulating that in my program?

    Seán

  4. #4
    Registered User
    Join Date
    Oct 2011
    Posts
    23
    Try using Quick'n'Dirty bitmap. It's a nice library that can help you manipulate bitmaps and it also quite fast.
    QDBMP

    Also, it has a tutorial of how to negate an image.

    Good luck!

  5. #5
    Registered User
    Join Date
    Nov 2009
    Posts
    43
    run 2 for loops one nested in another
    outer 1 for height inner 1 for width ... read it as a byte in character .. use & operator .. negate it .

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    You need to find out about your image format in the header, bitdepth, layout, and so on. Then you just iterate your image buffer, (probably don't touch the alpha channel) and xor each RGB value with 0xff. But this depends on how the pixels are stored.

  7. #7
    Registered User
    Join Date
    Oct 2011
    Location
    Ireland
    Posts
    30
    Hey,

    Thanks for all the replies ...I am going to have a go at this now. I am sure I will be back when I run into problems!

    Seán

  8. #8
    Registered User
    Join Date
    Oct 2011
    Location
    Ireland
    Posts
    30
    Quote Originally Posted by trish View Post
    .. use & operator .. negate it .
    Hello.

    I use the & operator to negate the value being used to give the colour? How do I do that?

    Seán

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by o.fithcheallaig View Post
    Hello.

    I use the & operator to negate the value being used to give the colour? How do I do that?

    Seán
    I don't know how you would use AND to negate a color. Assuming for example that you have a pixel struct with the pixels rgba values represented as unsigned chars you could negate each of them with xor (exclusive or) like this:

    Code:
    pixel.r ^= 0xff;
    Let's say that your red color has value 55, then:

    00110111
    11111111 ^
    -----------
    11001000 = 200

  10. #10
    Registered User
    Join Date
    Oct 2011
    Location
    Ireland
    Posts
    30
    Hello.

    I have been trying to fingure this out all day, and with the help of Google and this good site, I think I have a program that will copy the original file, into a new file. My plan is then to negate that file.

    But before that, I have an issue, maybe a few! I do not know what sizes to make the data array. I do not know what image will be loaded it, so I don't know what to put here. How should I handle this?

    Also, I am not sure about the structure of the code I need to negate the copied image, which I will save back into copy when it is done.

    Any advice would be very welcome.

    Code:
    #include <iostream>
    #include <stdio.h>
    #include "windows.h"
    
    using namespace std;
    
    int main()
    {
        FILE *ptrBmpFile, *ptFile;
        int number;
        unsigned char data [][][];
    
        BITMAPFILEHEADER bMapFileHeader;
        BITMAPINFOHEADER bMapInfoHeader;
    
        ptrBmpFile = fopen("Enter file name.bmp", "rb");
        fseek(ptrBmpFile, 0, SEEK_SET);         //Go to the start of the file
    
        //copies BITMAPFILEHEADER and BITMAPINFOHEADER
        num = fread(&bMapFileHeader, sizeof(BITMAPFILEHEADER), 1, ptrBmpFile);
        num = fread(&bMapInfoHeader, sizeof(BITMAPINFOHEADER), 1, ptrBmpFile);
    
        ptBmpFile = fopen("Enter file name for copy of image.bmp", "w")
    
        
        //creates empty file for writing
        fseek(ptBmpFile, 0, SEEK_SET);
        num = fwrite(&bMapFileHeader, sizeof(BITMAPFILEHEADER), 1, ptBmpFile);
        num = fwrite(&bMapInfoHeader, sizeof(BITMAPINFOHEADER), 1, ptBmpFile);
    
        //Get the beginning of the data in the bitmap
        fseek(ptr, 0, SEEK_SET);
    
        //Read in the bitmap fil
        fread(data, bMapInfoHeader.biSizeImage, 1, ptrBmpFile);
        fclose(ptrBmpFile);
    
        //Copy image
        fseek(ptrBmpFile, 0, SEEK_SET);
        fwrite(data, bMapInfoHeader.biSizeImage, 1, ptBmpFile);
        fclose(ptBmpFile);
    }
    Thanks.
    Seán

  11. #11
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Are you using C or C++? Namespaces and <iostream> are C++ only. Also, line 11 won't compile (at least in C), so is it also some kind of C++ standard?

  12. #12
    Registered User
    Join Date
    Oct 2011
    Location
    Ireland
    Posts
    30
    Hello, will it not compile because the brackets are empty? That is one of my problems, I don't know what I should be putting in them.

    I open a blank C++ file, but I am trying to write more in C. If there is something I don't know how to write in C, I might know in C++.

    I know this is not a good way to write, but if it gets me where I need...

    Seán
    Last edited by o.fithcheallaig; 01-22-2012 at 05:41 PM.

  13. #13
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Use C, it can do what you're trying to do.

    If you don't know the sizes, look into dynamic memory allocation. I find it questionable, however, that it's 3D, as it should only be dealing with X and Y coordinates. A quick example:

    Code:
    int16_t size_x = 500;
    int16_t size_y = 500;
    /* replace 500 with the actual x & y of the image, find it programatically */
    
    char **data = malloc(size_x); 
    int16_t tmp = size_y;
    while (tmp--) 
        data[tmp] = malloc (size_y); 
    /* now you can reference it, for example, if you want to set X=50 and Y=67: */
    data[50][67] = 0; 
     
    
    /* when you're done, free everything */

  14. #14
    Registered User
    Join Date
    Oct 2011
    Location
    Ireland
    Posts
    30
    Hi, thanks for the reply.

    Can I see if I have this code right in my head. You are initially giving size_x and size_y a value of 500 each. Then you are allocating memory of the size size_x ...right?

    Then you are setting a variable tmp to equal 500, and while you decrement it ...well, I kind of get lost here ...sorry

  15. #15
    Registered User
    Join Date
    Oct 2011
    Location
    Ireland
    Posts
    30
    I think I have half the negating part figured out, but I am just not sure how to do the last bit of it

    Code:
    RGBQUAD rQuad
    /---------/
    for(int row = 0; row < bMapInfoHeader.biHeight; row++)
        {
            for(int column = 0; column < bMapInfoHeader.biWidth; column++)
            {
                red = rQuad.rgbRed;
                green = rQuad.rgbGreen;
                blue = rQuad.rgbBlue;
            }
        }
    And then I think I need 255-red, 255-green, 255-blue

    But I am not sure how to implement this ...I was think about 'puts' or 'fputs' but I am not sure really.
    Last edited by o.fithcheallaig; 01-22-2012 at 08:51 PM. Reason: Fixing code

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bitmap Image In C
    By snayyer in forum C Programming
    Replies: 9
    Last Post: 06-20-2011, 10:16 AM
  2. get bitmap from image in website.
    By sgh in forum C# Programming
    Replies: 3
    Last Post: 03-23-2009, 09:34 PM
  3. how to convert a bitmap image to a jpg image file using C++?
    By nomer in forum Windows Programming
    Replies: 4
    Last Post: 06-04-2006, 07:40 PM
  4. Reading a bitmap image
    By usamaalam in forum C Programming
    Replies: 19
    Last Post: 03-06-2004, 06:13 AM
  5. Hello all (re:bitmap image file)
    By Plastyksouljah in forum C++ Programming
    Replies: 7
    Last Post: 11-21-2003, 10:07 PM