Programming help with Binary image file with raw image format

Posted on 2011-10-10
Last Modified: 2012-06-27
The program is supposed to retrieve the Red, Blue and Green components on a given coordinate of an image.  The image has a RAW format and has a 100 x 100 pixel resolution.  This is what the program must have:
•      Three unsigned char fields r, g, b have to defined in a struct.
•      The user must enter the file name with the extension of .raw.
•      The (x, y) coordinate must be two numbers between 0 and 99. If not the program has to display a message and exit.
•      Use seekg to the corresponding location in the image file and then retrieve the color information with this formula:      loc = (y * image_x + x) * 3;    (image_x is always equal to 100).
•      Display the 3 numbers red, green, blue.
I’m having trouble with the user entering the file name, with the use of the seekg, and with the display of the numbers of green, red, blue.
Here is the program, what can I do to make it run as it should?
Thank you.

// Binari Image File
#include <iostream>
#include <fstream>
using namespace std;

//Structure for Red, Blue and Green
struct RGB
	unsigned char r;	//red
	unsigned char g;	//green
	unsigned char b;	//blue

int main()
	int x, y, loc;
	ifstream fileName;
	char data[100]; 
	int image_x = 100;

	RGB coordinate;

	//The user needs to enter the image name having a RAW format. The image has 100 x 100 pixel resolution.
	cout << "Enter the image name: " << endl;
	//cin >> fileName;

	//The user will enter a coordinate x and y. The coordinates must be between 0 and 99.
	cout << "Enter the pixel coordinate (x, y): " << endl;
	cin >> x >> y;

	if((x < 0) ||(x > 99) || (y < 0) || (y > 99))
		cout << "Error x and y must be between 0 and 99." << endl;
		return 0;
   // Open the file for input., sizeof(data));
   if (!fileName)
      cout << "Cannot open " << fileName << endl;
      return 0;

	loc = ((y + image_x + x) * 3);

	fileName.seekg(loc, ios::beg);

	//This will retrieve the RGB components depending on the coordinate.
	cout << "RGB Color at (" << x << ", " << y << "): " << endl;
	cout << coordinate.r << coordinate.g << coordinate.b;

   // Close the files.
   return 0;

Open in new window

Question by:MEAM
    LVL 15

    Expert Comment

    by:Minh Võ Công
    loc = (y+image_x*x)*3 ;  //image_x = 100
    LVL 32

    Expert Comment

    the filename is an ifstream. so you can't get input from cin where the user types a string. i would say filename is a poor name for a stream. better use

    std::string filename;
    std::ifstream file;
    std::getline(cin, filename);;
    if (!file)
        // error

    Open in new window

    the getline has the advantage that the path to the file can contain spaces.


    Author Comment

    Thank you, the user can now enter the filename correctly.

    What I need now is help on how to perform a random access (using seekg) correctly, it is still not showing the red, blue and green colors for the image.

    Thank you for your help.
    LVL 32

    Accepted Solution

    a seekg doesn't make sense if the file is a text file.  in a text file the lines have variable size and were terminated by linefeed (and carriage-control on windows platform) character. so you can't actually calculate where an RGB triple starts in a text file.

    if the file is a binary file what the "raw stream format" seems to imply you should open the file with open flag std::ios::binary especially when you are at windows platform where text mode is default and any pair 0x0d 0x0a would be transformed to a single 0x0a (linefeed) when reading.
    so use, std::ios::in | std::ios::binary);

    Open in new window

    to specify a binary read.

    the formula "(y * image_x + x) * 3" would calculate the byte position within the file for a point (x, y).

    if  (x, y) is for example (20, 50) the position would be

        (50*100 + 20)*3 = (5020)*3 = 15060

    that is 15,000 bytes for the rgb-triples of row 0 to 49 (50 rows with 100 pixels and 3 bytes each)  plus the 60 bytes for the pixels 0 to 19 in row 50.

    if you do a seekg on that location you can read 3 bytes from there.

    for that read you need an object of RGB structure.

    RGB pixel;

    Open in new window

    and the read it from file at the current position after seekg. so your current read from file is wrong (it reads only 100 bytes from begin) and at the wrong position. instead you need to exchange the 'data' argument in the read by '(char*)&pixel' and the size argument by sizeof(pixel). the cast to char* is necessary cause the read expects a char buffer and not a RGB buffer.

    finally you could access the colors read by using the RGB members for example


    Author Comment

    The only part im having trouble now is with seekg.  How should the seekg statement be?
    Thank you.
    LVL 32

    Expert Comment

    your seekg statement looks fine. you only need to calculate loc correctly (the formula minhvc has posted is wrong, you have to take the one specified in your assignment) and move the seekg call after opening the file in binary mode.

    the seekg has two arguments. the first is the fileposition in bytes relative to the place specified with the second argument. that argument is an enumeration with three possible constants: ios::beg means relative to begin of file. ios::cur means relative to current file position (what would be used if you already read some parts and want to skip some other part) and ios::end means relative from end-of-file. the latter is used often for evaluating log files where the youngest lines are at end.


    Author Comment

    Yes. The problem was with the loc formula. I changed it and it worked correctly. Thank you very much for your help.

    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Join & Write a Comment

    Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
    Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
    The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
    The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

    745 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    16 Experts available now in Live!

    Get 1:1 Help Now