-
January 21st, 2012, 07:48 PM
#1
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
-
January 22nd, 2012, 08:32 AM
#2
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
-
January 22nd, 2012, 08:38 AM
#3
Re: Negating a bitmap image
Hey, thanks for the reply.
Originally Posted by S_M_A
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.
-
January 22nd, 2012, 09:18 AM
#4
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
-
January 22nd, 2012, 11:50 AM
#5
Re: Negating a bitmap image
Originally Posted by o.fithcheallaigh
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
-
January 22nd, 2012, 11:54 AM
#6
Re: Negating a bitmap image
Originally Posted by o.fithcheallaigh
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
-
January 22nd, 2012, 11:56 AM
#7
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.
-
January 22nd, 2012, 12:33 PM
#8
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
-
January 22nd, 2012, 03:48 PM
#9
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
-
January 22nd, 2012, 04:52 PM
#10
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
-
January 22nd, 2012, 05:11 PM
#11
Re: Negating a bitmap image
-
January 22nd, 2012, 07:00 PM
#12
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
-
January 22nd, 2012, 08:04 PM
#13
Re: Negating a bitmap image
Originally Posted by monarch_dodra
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.
Originally Posted by o.fithcheallaigh
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.
-
January 23rd, 2012, 05:12 AM
#14
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
-
January 23rd, 2012, 08:56 AM
#15
Re: Negating a bitmap image
Originally Posted by o.fithcheallaigh
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|