Invert RGB Colors of a bitmap image using C++ in Microsoft Visual Studio.

Hello all!
I am new to C++ coding using Visual Studio and this is my first post.
I need help in creating a program in C++ without using structures which can read RGB colors values of a 24 bit bitmap image file and invert its values and save it in another file using instream and outstream functions.

Thank you!
Last edited on
We are not a code writing service. If you want to learn programming, make a plan and start writing some code and if you get stuck you can get help.
First thing you would need to do is to learn about the 24bit bitmap fileformat - Google is your friend.

If you don't want to learn better go to:
https://www.assignmentexpert.com/blog/do-my-c-homework/
http://www.tutorsonnet.com/c++-programming-homework-help.php
There is no the format. There are several bitmap file formats that store 24bit data.

There is most likely a C or C++ library for your file format. Types and functions, just like the iostream and fstream are types and functions that you intend to use.

Forget the without using structures. Use the existing codebase, even if that presents structures. You don't want to recreate image file format handling in your code.
ok thanks but how to read values of Blue Red Green in an image?
Does it have anything to do with the start of data bytes in an image? How to use them in an array using a for loop. Secondly sorry thomas didnt meant for someone writing the code. My bad. Just meant the initialization of colors and how to use them. I have googled it and read about it as well was stuck in this part. Couldnt percieve from where to start a code. Sorry again.
Last edited on
OK, no problem.
Are you familar with reading and writing binary data and C++ streams ?
If not a good starting point would be just to create a simple app that read and write some bytes to a file. Maybe you also can find out what file you need to use - I guess this is a kind of assignment.
Yup can read and write data using C++ streams.
ofstream myfile("example.txt",ios::binary);
unsigned char Alphabet = 'B';
unsigned char Array[] = "A byte array";
if (myfile.is_open())
{
myfile << "This is a line.\n";
myfile << Alphabet;
myfile << Array;
myfile.write((char*)Array, sizeof(Array));
myfile.close();
}
else cout << "Unable to open file";
Simple code for writing data in a txt file.
Same can be written into another file using instream & outstream.
This is obviously not what you want to do:
http://doc.qt.io/qt-5/qimage.html#reading-and-writing-image-files
1
2
3
4
5
6
7
8
9
10
11
QImage bar( "foo" );
if ( ! bar.isNull() ) {
  for ( int x = 0; x < bar.width(); ++x ) {
    for ( int y = 0; y < bar.height(); ++y ) {
      auto value = bar.pixel( x, y );
      // change value
      bar.setPixel( x, y, value );
    }
  }
  bar.save( "invfoo", "PNG" );
}

The point is that the first line alone does all the file reading and the actual "RGB value" manipulation happens on what is apparently 2D array in dynamic memory. This QImage "struct" hides the details and just offers pixel() and setPixel() "getter/setter".

Okay, you don't want to do that. You want to read the file manually. You want to write a coherent file manually. You have to know exactly what is and what must be in the file, in order to do everything yourself.

The QImage knows 10 bitmap file formats, but can write only 7. You need to read/write only one.
Ok. That helps a lot keskiverto. Will try to create my code and then share again.
Thanks guys.
I have tried this code. It is creating a file but not inverting the values of bmp image.

int SOD = ((data[10]) + (data[11]*256) + (data[12]*256*256) + (data[13]*256*256*256));
unsigned char* invert = new unsigned char[SOD];
in.open("abc.bmp",ios::binary);
ofstream out("imgInvert.bmp",ios::binary);
if (in.is_open() && out.is_open());
{
while (!in.eof())
{
for(int j=SOD; j=in.eof() ; j++)
{
in.get() >> (255 - invert[j]);
}
out.put(in.get());
}
}

Can anyone help?
What is data? It looks like an array of characters, but what values does it contain? I would think it should be unsigned char for that sort of calculation, otherwise negative numbers can cause unwanted results.

This line should not end in a semicolon
 
    if (in.is_open() && out.is_open());


The rest of the code looks a bit mangled too. Loops which use while (!in.eof()) are very usually wrong, and there are better ways.

This looks suspicious:
 
    for(int j=SOD; j=in.eof() ; j++)

This j=in.eof() is an assignment statement, if eof is false, then it is equivalent to j=0 which in turn evaluates as false, meaning the loop does not execute.


Last edited on
you are right
if (in.is_open() && out.is_open()); should not end with ;. that was a mistake.

Secondly these were the initializations:

int headerSizeF = 54;
unsigned char* data = new unsigned char[headerSizeF];
int SOD = ((data[10]) + (data[11]*256) + (data[12]*256*256) + (data[13]*256*256*256));
unsigned char* invert = new unsigned char[SOD];
What you could do is something like this. It just makes a straight copy of the input file to the output with no changes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <fstream>

using namespace std;

int main()
{        
    ifstream fin("abc.bmp", ios::binary);
    ofstream fout("imgInvert.bmp", ios::binary);
        
    char byte;
    
    while ( fin.get(byte) )
    {
        fout.put(byte);
    }
        
}


If we make lots of assumptions about what sort of format the bmp file has, then we can build on that.

1. use a loop to copy the first 54 bytes from input to output - as above, but use a count to limit it to just 54 iterations.

2. use another loop, almost identical to the loop in my example. The only change needed is to invert the value of byte before the fout.put() What does invert mean? I assume it means subtract byte from 255 to get the new value.

Using this approach, there is no need for any of the complex processing your code was doing.

I did write another version (not shown here) where I used seekg() to move to offset 10 in the input, read a 4-byte unsigned integer, then reset the position to the start using seekg. That meant instead of assuming the pixel data was at offset 54, I used the actual value read from the file.

To understand the bmp format, I referred to this simplified page:
http://www.dragonwins.com/domains/getteched/bmp/bmpfileformat.htm

Thank you for ur time. Its really been helpful. I understand the concept of it now. Basically i have to read the headersize as it is in the output file and the remaining data needs to be 255 - input file.
Really grateful.
Topic archived. No new replies allowed.