Click here to Skip to main content
15,891,943 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
okay, what i've been doing recently has been giving me a massive headache, and i think i need a little help. what i'm trying to do, is just read from a normal bitmap file, it's width, height, and than feed all the data for each individual pixel into an array of structures. what i came up with is below:

C++
#include <fstream>
#include <iostream>
#include <string>
using namespace std;


struct PIXEL
{
	unsigned char r, g, b;
};

int main(int argc, char *argv[])
{
	ifstream image;
	int width, height;
	PIXEL * pixeldata;
	int imageIdx = 0;
	unsigned char temp;
	// picture.bmp is just a random picture i have
	image.open("picture.bmp", ios::in | ios::binary);
	image.seekg(18);
	image.read((char*) &width, 4);
	image.read((char*) &height, 4);
	image.seekg(54);

	pixeldata = new PIXEL[width - 1, height - 1 ];
	int rowcount = 0;
	for(int y = height - 1; y >= 0; y--)
	{
		rowcount = 0;
		for (int x = 0; x < width; x++)
		{
			if(image.eof() ) break;
			image.read((char*) &pixeldata[x, y].b, 1);
			image.read((char*) &pixeldata[x, y].g, 1);
			image.read((char*) &pixeldata[x, y].r, 1);
			rowcount += 3;
		}

		while(rowcount % 4)
		{
			image.read((char*) &temp, 1);
			rowcount++;
		}
	}
	image.close();

        // this just prints out the data so i can compare it to the original file
	for (int i = 0; i< 50; i++)
	{
		for( int y = 0; y< 20; y++)
		{
			cout << "  pixel: (" << i << "," << y << ")   "
				 << (int) pixeldata[i,y].r << "   " << (int) pixeldata[i,y].g << "   " << (int) pixeldata[i,y].b << "\n";
		}
	}
	system("PAUSE");
}


this is utterly disfunctional :( .I figure there has to be a more straightforward way than this that either c++ or windows provides. can anyone provide any insight into this? my ultimate goal here is be able to load a bitmap and all of it's pixel data into a multidimentional array like i did, the x and y values starting in the top left, and then be able to change some rgb values of the individual pixels, and then output the new pixel data to the same bitmap file. i know how i would go about changing the pixel data, but i literally have no idea how to do the output so that nothing is changed besides the pixel data :( , any help is appreciated.
Posted

You should study the BMP file format[^] if you want to do the whole thing "by hand". Looking at your code i'd say:
-note that not every BMP is 24 bits per pixel, that is, 1 byte for red, 1 byte for green and 1 byte for blue.
-note that this:
pixeldata = new PIXEL[width - 1, height - 1 ];
does not allocate a buffer of (width - 1) by (height - 1) PIXEL structures, what you probably want here is:
pixeldata = new PIXEL[(width - 1) * (height - 1)];
and then, why minus one? Shouldn't it be
pixeldata = new PIXEL[width * height]
?
 
Share this answer
 
Comments
FatalCatharsis 29-Sep-11 9:55am    
no, i'm not trying to make an array with one single index of height*width pixel values, i'm trying to make a multidimentional array, where each width index has height number of corresponding indices. it will technically have the same number of total indices as an array of height*width, but i feel it is a little more easy to work with, because you can just put in the x and y indices to find the pixel at that spot on the x, y axis. For example instead of having to know that point (0,3) in a 4x4 bitmap is array position 15, (because it reads from the bottom row, left to right), i can just look at pixel[0,3] and there you go. personally i love multidimentional arrays for simplicity, which is what i implemented there. the reason i used width -1 and height -1 because the height and width values are the number of pixels along the width and height, not starting from zero. so say i i have a picture that say it has a width 12 and height of 12. it would start from index value 0 and go to 11 to store all the values for that row. so that's why i'm doing what i'm doing. however, i don't think i'm receiving the values in the correct order, which is why mine program doesn't work right now :(
Code-o-mat 29-Sep-11 10:12am    
I see, but with this:
new PIXEL[width - 1, height - 1 ];
you are not creating a two dimensional array of (with - 1) by (height - 1) items, you are basicly creating a one dimensional array of (height - 1) items.
Check out this[^] for an explanation. Similary to that, here: pixeldata[x, y], you are accessing the "y-th" element of the one dimensional array.
What you can do is create the 1 dimension array of width*height items, and then if you want to address the item at x,y, you access the "y * width + x"-th item. You can write a nice macro to simplify this or create some wrapper and define an operator for accessing the data.
FatalCatharsis 29-Sep-11 11:27am    
interesting, i see what your saying, i tried to make a 2 dimensional array the normal way before, like
pixel[width-1][height -1]

but it wouldn't work with the dynamic allocation, claiming that the first value had to be a constant or something, i guess i'll just make it one dimensional and make a macro. I'll post back later saying whether it worked or not, thank you so far for you help!
FatalCatharsis 29-Sep-11 11:36am    
i'm not currently at a place where i can work on it, but another thought just occured to me. could i make a more normal 2 dimensional array by doing something like this?

pixels = new PIXEL[width];
for (int i = 0; i < width; i++)
pixels[i] = new PIXEL[height]

it might be allocated weird, but i could still access it like i normally like to, pixels[width][height] ya know?
Code-o-mat 29-Sep-11 11:55am    
If you don't mind the "weird" allocation as you said, then:
typedef PIXEL *LPPIXEL;
LPPIXEL *pixels = new LPPIXEL[width];
for (int x = 0; x < width; x++)
pixels[x] = new PIXEL[height];
...
pixel[x][y].r = ...
...
or something similar should work.
If you are free to use third party libraries i would suggest you to have a look into e.g. openCV or ITK since they are highly compatible with C++ and ease the work with images a lot. Im pretty sure that there are even more open source libraries out there which provide the functionality you're looking for.
 
Share this answer
 
Comments
FatalCatharsis 29-Sep-11 9:34am    
sorry, i wasn't very clear :P , i'm trying to avoid learning a new third party api just for one simple project. if i could stick with windows or direct x that would be great, but if i have no more options, then i guess i will :P

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900