CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Oct 2011
    Posts
    91

    Negating a bitmap image

    Hello.

    I hope everyone is well.

    I also hope someone can tell me if I am going along the right path in writing a program to negate a bitmap image. The program as I have it is asking the user to input a value for the RGB values. But how do I set it up to give the negative of each colour? It has been suggested using the & operator to negate the image inside nested loops.

    Also, the RGBQUAD structure was copied into my main program from a BITMAP.H file we were given. However, is it okay just to leave that in the .h file, and just call it from my main program ....if that makes sense?

    Anyway, here is my code so far
    Code:
    #include <iostream>
    #include <fstream>      //Used for file I/O
    #include <cstdlib>      //For exit
    #include <string>
    #include <algorithm>  // for remove_if
    #include <cctype>     // for iswspace
    
    using namespace std;
    
    ifstream inStream;
    ofstream outStream;
    
    char input[100], output[100];
    //int redValue, greenValue, blueValue;
    
    typedef struct                       /**** Colormap entry structure ****/
        {
            unsigned char  rgbBlue;          /* Blue value */
            unsigned char  rgbGreen;         /* Green value */
            unsigned char  rgbRed;           /* Red value */
            unsigned char  rgbReserved;      /* Reserved */
        } RGBQUAD;
    
    int main()
    {
        cout << "Enter the input filename: \n";
        cin >> input;
    
        inStream.open(input);       //Open the file
        if(inStream.fail())
        {
            cout << "File opening failed.\n"
            exit(1);
        }
    
        cout<<"Enter output filename.\n"; // Should be "abbccde.txt"
        cin >> output;
    
        outStream.open(output); //Open/Create outfile.txt
        if(outStream.fail())           //Check
        {
             cout<<"Output file opening failed.\n";
             exit(1);
        }
        
        cout << "Enter a value on the RGB scale to alter the Red value: \n";
        cin >> RGBQUAD.rgbRed;
        
        cout << "Enter a value on the RGB scale to alter the Green value: \n";
        cin >> RGBQUAD.rgbGreen;
        
        cout << "Enter a value on the RGB scale to alter the Blue value: \n";
        cin >> RGBQUAD.rgbBlue
    }
    Thanks for any input.

    Seán

  2. #2
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: Negating a bitmap image

    It's more than ok to leave the declaration in the header and just include it. In fact that's the normal way of using something like a library/module/class. Just like you do with for instance iostream

    Regarding the negating the color. You just have to change each individual color value to the value that makes the sum of positive and the negative equal to full scale. I.e. with a notation invented just at this moment R+ + R- = 255, B+ + B- = 255, G+ + G- = 255
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  3. #3
    Join Date
    Oct 2011
    Posts
    91

    Re: Negating a bitmap image

    Hey, thanks for the reply.

    Quote Originally Posted by S_M_A View Post
    Regarding the negating the color. You just have to change each individual color value to the value that makes the sum of positive and the negative equal to full scale. I.e. with a notation invented just at this moment R+ + R- = 255, B+ + B- = 255, G+ + G- = 255
    Okay, that makes sense. But do I just need this for the RGB colours? What about yellow etc?

    And this presents another problem. Knowing what colour they are, so I can negate them.

  4. #4
    Join Date
    Oct 2011
    Posts
    91

    Re: Negating a bitmap image

    I have been looking at other bits of code I have, and I was wondering would this be a reasonable way to do it.

    In the bitmap.h file I have a structire called BITMAPINFOHEADER which contains elements for the weight, width etc. So I was wondering about creating a new stucture in my program, called somthing like imageCopy, and putting these values into it to defind the size of the image.

    This could then be used in the main part of my program, along with some loops to go through the pixels, and negate them.

    But I still don't know how to find out what colour they are to begin with, so I can negate them.

    Seán

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Negating a bitmap image

    Quote Originally Posted by o.fithcheallaigh View Post
    Also, the RGBQUAD structure was copied into my main program from a BITMAP.H file we were given. However, is it okay just to leave that in the .h file, and just call it from my main program
    1) What was wrong with just including bitmap.h?

    2) This code shouldn't compile, and any code that looks like this in your example shouldn't compile:
    Code:
     cin >> RGBQUAD.rgbRed;
    RGBQUAD is a type, it isn't a variable.
    Code:
    RGBQUAD rQuad;
    //...
    cin >> rQuad.rgbRed;
    This is an example of what the code should look like.

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Negating a bitmap image

    Quote Originally Posted by o.fithcheallaigh View Post
    I have been looking at other bits of code I have, and I was wondering would this be a reasonable way to do it.

    In the bitmap.h file I have a structire called BITMAPINFOHEADER which
    Are you working with the Windows OS? If you are, then it makes more sense to obtain the hundreds, if not thousands of examples of how to manipulate bitmaps using the Windows structures such as RGBQUAD and BITMAPINFOHEADER. There are even free libraries with full C++ source showing you how to negate, flip, mirror, etc. Windows bitmaps.

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Negating a bitmap image

    I'm no photograph or image processing specialist, but given that there are different color spaces (RGB, YUV, CMYK, just to name a few...), are you certain that a "negative image" is just the inverse of the RGB space?

    If what you are going for is obtaining the same effect as a negative photographic film, well, I'm not sure you'll get the "correct" effect (you'll obtain something, what, I'm not sure).
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  8. #8
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: Negating a bitmap image

    I'm no image specialist either but in the past I did some photographing in black & white and I had a private dark room so I just applied how it works in BW. I don't think that there is some kind of mystery added just because it's colors involved but you're right monarch_dodra, it's better to do some research to be sure.

    Yellow is a mixture of red and green. Maybe reading this helps http://en.wikipedia.org/wiki/RGB_color_model
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  9. #9
    Join Date
    Oct 2011
    Posts
    91

    Re: Negating a bitmap image

    Hello.

    Thanks for the infor on the RGB colour system. I should have realised that by altering any of the RGB values, it will effect all colours.

    And Paul, thanks for the reminder on the RGBQUAD code!

    I assume I am going along the right lines here ...somewhat anyway! But I was just wondering something, and I hope I can state this clearly...

    When the program opens a bitmap image, will it have an associated BITMAPINFOHEADER etc with it? I assume it must, since this will define the height, width etc.

    I am wondering because I want to know if I can make a copy of those structures (i.e. the RGBQUAD, BITMAPINFOHEADER) and alter them?

    If I can't do that, I don't see how I can get the information for the file, to alter it! If that makes sense.

    I should say that we have not been given a bitmap to alter, this program should work for any give bitmap.

    Thanks again.

    Seán

  10. #10
    Join Date
    Oct 2011
    Posts
    91

    Re: Negating a bitmap image

    I think my problem here is understad the steps I need to go through. I mean, I can figure the code out when I know WHAT to do.

    For example.

    1. Open the file.
    2. Copy header information into new structure (if this was a step, I dont know how to do this)
    3. Run loops to negate image.
    4. Save under new file name.
    5. close all files.

    This is what I think I need to do ...But I am not sure.

    Seán

  11. #11
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: Negating a bitmap image

    Sounds alright to me
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  12. #12
    Join Date
    Oct 2011
    Posts
    91

    Re: Negating a bitmap image

    Hey,

    I have got this written in C (I know this is a C++ board, sorry).

    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.

    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

  13. #13
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Negating a bitmap image

    Quote Originally Posted by monarch_dodra View Post
    I'm no photograph or image processing specialist, but given that there are different color spaces (RGB, YUV, CMYK, just to name a few...), are you certain that a "negative image" is just the inverse of the RGB space?

    If what you are going for is obtaining the same effect as a negative photographic film, well, I'm not sure you'll get the "correct" effect (you'll obtain something, what, I'm not sure).
    RGB colors can be inverted the way described by S_M_A. There certainly are some fancier ways of color inversion, in particular when it comes to "high-end" color spaces like Lab, but the straightforward brute force method should be sufficient for most cases. (Also, these "high-end" color spaces are commonly used to overcome some inherent shortcomings of the RGB space, so applying color inversion schemes created for them probably wouldn't make much sense when applied to plain RGB data anyway.) I don't think it's a good idea to simply extend that scheme to RGBA colors, though. The A component should be left unchanged instead, or treated separately.

    CMYK colors can't be inverted that way. They may be inverted instead by performing an inverse undercolor removal, thereby eliminating the black component, inverting the C, M and Y components as described, an then re-applying undercolor removal. I'm not sure about YUV, but IIRC it encodes the colors as a set of three vectors, and inverting them is probably done by reversing two of the vectors or all three.

    The described way of inverting colors will not, however, reproduce the effect observed on color negative film commonly used in chemical cameras. The reason for that isn't that the color inversion scheme is wrong, it's the fact that the base material of the chemical film has a certain standardized orange color of its own. In fact, when scanning color negatives, the effect of that so-called (at least in Germany) "mask" needs to be computationally compensated in order to obtain proper RGB (or whatever color space) images.

    Quote Originally Posted by o.fithcheallaigh View Post
    2. Copy header information into new structure (if this was a step, I dont know how to do this)
    If you're not going to change anything else than pixel color values, you may leave the header unchanged and consequentially I don't see a compelling need to make a copy of it in memory either. (However, note that when inverting palettized images, the color inversion needs to be applied to the palette, not the pixel values. I don't know whether you're required to support that specific variant of the bitmap format at all, though.)
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  14. #14
    Join Date
    Oct 2011
    Posts
    91

    Re: Negating a bitmap image

    Hello,

    No, we have not been asked to support any specific variant of bitmap.

    Could I ask one last question on this? It has to dowiththe code for negating the colours. I have put the code I have below, but I don't know how to finish 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' (or the C++ equivalent) but I am not sure really.

    Thanks.

    Seán

  15. #15
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Negating a bitmap image

    Quote Originally Posted by o.fithcheallaigh View Post
    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' (or the C++ equivalent) but I am not sure really.
    Why so complicated? Simply modify the pixel data in memory and write it to the output file as a whole, much like you probably have read it already. (BTW, fputs() is for textual data, not binary data like the pixel values. And puts() is for console output rather than writing to files anyway.)
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured