• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 340
  • Last Modified:

Programming help with Binary image file with raw image format

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;
	}
	else 
 
   // Open the file for input.
  fileName.read(data, 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.
   fileName.close();
   
   return 0;
}

Open in new window

0
MEAM
Asked:
MEAM
  • 3
  • 3
1 Solution
 
Minh Võ CôngCommented:
loc = (y+image_x*x)*3 ;  //image_x = 100
0
 
sarabandeCommented:
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);
file.open(filename.c_str());
if (!file)
{
    // error

Open in new window


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

Sara
0
 
MEAMAuthor Commented:
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.
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
sarabandeCommented:
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

file.open(filename.c_str(), 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 pixel.red

Sara
 
0
 
MEAMAuthor Commented:
The only part im having trouble now is with seekg.  How should the seekg statement be?
Thank you.
0
 
sarabandeCommented:
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.

Sara
0
 
MEAMAuthor Commented:
Yes. The problem was with the loc formula. I changed it and it worked correctly. Thank you very much for your help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now