I'm writing a c++ program that manipulates images, and this is the function to shrink it. There is a 'pixel' pointer array and a class that has the image colors defined. I cannot use any other library besides the ones included in Visual Studio for this image program. I'm having an issue with this function, I need to traverse the pixels in the image and split it into blocks; the user will enter the block width/height. After the blocks are created, the average RGB values need to be taken from each block (that average will become a single new pixel), and with all of them arranged it will 'shrink' the image. So far it seems the blocks are created because the image becomes smaller, but my image turns completely gray. The totals for the RGB pixels are adding correctly, but something must be off in the rest of the code and I haven't been able to pinpoint it. Here is my code:
//creates a block of average colors based on range of pixels given
pixel CreateBlock(int start, int stop, pixel** currpix, int blockHeight, int blockWidth)
{
pixel** block; //Problem? might have to be a single pointer pixel* block[];
block = new pixel*[blockHeight];
for (int i = 0; i < blockHeight; i++)
block[i] = new pixel[blockWidth];
pixel newPix;
float totred = 0, totblue = 0, totgreen = 0;
int redav = 0.0, blueav = 0.0, greenav = 0.0;
for (int i = 0; i < blockHeight; i++)
{
for (int j = 0; j < blockWidth; j++)
{
totred = totred + block[i][j].red;
totblue = totblue + block[i][j].blue;
totgreen = totgreen + block[i][j].green;
}
}
redav = totred / (blockHeight*blockWidth);
blueav = totblue / (blockHeight* blockWidth);
greenav = totgreen / (blockHeight*blockWidth);
newPix.red = redav;
newPix.blue = blueav;
newPix.green = greenav;
return newPix;
}
//make a new image that is a smaller resampling of the bigger image
void averageRegions(int blockWidth, int blockHeight)
{
int height = displayed->getHeight(), width = displayed->getWidth();
int i = 0, j = 0;
pixel** currpix = displayed->getPixels(); //PROBLEM
image* shrunk = displayed;
//shrunk->getPixels();
shrunk->createNewImage(width / blockWidth, height / blockHeight);
while (i < height)
{
while (j < width)
{
int start = i, stop = i + 10;
shrunk->getPixels()[i][j] = CreateBlock(start, stop, currpix, blockHeight, blockWidth);
j = j + blockWidth;
}
i = i + blockHeight;
}
return;
}
Here is the image class:
class image {
public:
image(); //the image constructor (initializes everything)
image(string filename); //a image constructor that directly loads an image from disk
~image(); //the image destructor (deletes the dynamically created pixel array)
void createNewImage(int width, int height); //this function deletes any current image data and creates a new blank image
//with the specified width/height and allocates the needed number of pixels
//dynamically.
bool loadImage(string filename); //load an image from the specified file path. Return true if it works, false if it is not a valid image.
//Note that we only accept images of the RGB 8bit colorspace!
void saveImage(string filename); //Save an image to the specified path
pixel** getPixels(); //return the 2-dimensional pixels array
int getWidth(); //return the width of the image
int getHeight(); //return the height of the image
void viewImage(CImage* myImage); //This function is called by the windows GUI. It returns the image in format the GUI understands.
private:
void pixelsToCImage(CImage* myImage); //this function is called internally by the image class.
//it converts our pixel struct array to a standard BGR uchar array with word spacing.
//(Don't worry about what this does)
pixel** pixels; // pixel data array for image
int width, height; // stores the image dimensions
};
Here is the pixel class:
class pixel
{
public:
unsigned char red; //the red component
unsigned char green; //the green component
unsigned char blue; //the blue component
};
See Question&Answers more detail:os