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

Oct 27, 2017 at 9:58am
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 Oct 27, 2017 at 10:00am
Oct 27, 2017 at 11:01am
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
Oct 27, 2017 at 11:43am
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.
Oct 27, 2017 at 11:56am
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 Oct 27, 2017 at 11:58am
Oct 27, 2017 at 12:22pm
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.
Oct 27, 2017 at 12:31pm
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.
Oct 27, 2017 at 1:58pm
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.
Oct 27, 2017 at 4:06pm
Ok. That helps a lot keskiverto. Will try to create my code and then share again.
Thanks guys.
Nov 1, 2017 at 10:41am
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?
Nov 1, 2017 at 11:01am
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 Nov 1, 2017 at 11:03am
Nov 1, 2017 at 11:23am
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];
Nov 1, 2017 at 6:01pm
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

Nov 1, 2017 at 6:11pm
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.