访问私有数据以从图像中获取像素时C++错误

C++ error with accessing private data to get pixels from images

本文关键字:像素 获取 C++ 错误 图像 数据 访问      更新时间:2023-10-16

我正在编写一个使用填充图像创建马赛克的程序。 我在访问每个填充图像的像素的私人数据时遇到问题。 我可以从源图像(显示的图像*(中获取像素,但是当我尝试使填充图像缩小特定于输入的块大小时,我丢失了数据。 填充图像需要调整为块高度和块宽度,以便它们可以正确适应源图像的高度和宽度,这是 resizeFillerImage 函数的目标。在加载包含所有填充图像的文件夹时,我正在使用链接链接,并且在将它们加载到程序中时,我确实得到了正确的平均值。pixel** 数组是包含 fillerImage 类的主 Image 类中的私有数据,我无法更改它,因此我需要能够获取填充图像的像素并将它们设置为我创建的临时副本图像。

这是我的代码:

全局:

image* displayed;
fillerNode* head = NULL;
fillerNode* head2 = NULL;
fillerNode* temp1;
fillerNode* shrinkedList;
//This function will resize each filler image based on the block size
void resizeFillerImage(int blockWidth, int blockHeight)
{
    int blockSize = blockWidth * blockHeight;
    int avgRed = 0, avgGreen = 0, avgBlue = 0;
    image* temp = new image;
    temp->createNewImage(displayed->getWidth() / blockWidth, displayed->getHeight() / blockHeight);
    pixel** shrinkPix = temp->getPixels(); //THIS IS WHERE I GET THE ERROR
    //The pixel numbers get reset instead of being assigned to temp
    for (int i = 0; i < displayed->getHeight() / blockHeight; i++)
    {
        for (int j = 0; j < displayed->getWidth() / blockWidth; j++)
        {
            for (int k = 0; k < blockHeight; k++)
            {
                for (int m = 0; m < blockWidth; m++)
                {
                    avgRed = avgRed + shrinkPix[i * blockHeight + k][j * blockWidth + m].red;
                    avgGreen = avgGreen + shrinkPix[i * blockHeight + k][j * blockWidth + m].green;
                    avgBlue = avgBlue + shrinkPix[i * blockHeight + k][j * blockWidth + m].blue;
                }
            }
            avgRed = avgRed / blockSize;
            avgGreen = avgGreen / blockSize;
            avgBlue = avgBlue / blockSize;
            shrinkPix[i][j].red = avgRed;
            shrinkPix[i][j].green = avgGreen;
            shrinkPix[i][j].blue = avgBlue;
            avgRed = 0;
            avgGreen = 0;
            avgBlue = 0;
        }
    }
    for (int i = 0; i < displayed->getHeight(); i++)
    {
        for (int j = 0; j < displayed->getWidth(); j++)
        {
            if ((i > displayed->getHeight() / blockHeight) || (j > displayed->getWidth() / blockWidth))
            {
                shrinkPix[i][j].red = 0;
                shrinkPix[i][j].green = 0;
                shrinkPix[i][j].blue = 0;
            }
        }
    }
    displayed = temp;
    return;
}
//This function should generate the photomosaic from the loaded image.  Each filler image should represent a section of the original image
//that is blockWidth by blockHeight big.
void generateMosaic(int blockWidth, int blockHeight)
{
    for (int i = FIRST_FILLER_NUMBER; i <= LAST_FILLER_NUMBER; i++)
    {
        shrinkedList = new fillerNode;
        fillerImage* tempImage = new fillerImage();
        resizeFillerImage(blockHeight, blockHeight);
    }
}

下面是填充图像类:

fillerImage::fillerImage() //constructor
{
    this->timesUsed = 0;
    this->averageColor.red = 0;
    this->averageColor.green = 0;
    this->averageColor.blue = 0;
}
fillerImage::fillerImage(string filename) : image(filename)
{
    timesUsed = 0;
}
fillerImage::~fillerImage() //destructor
{
    timesUsed = NULL;
    averageColor.red = NULL;
    averageColor.green = NULL;
    averageColor.blue = NULL;
}
void fillerImage::calculateAverageColor() //calcuate the average color assign that color to private  member averageColor
{
    pixel** pix = getPixels();
    int area = FILLER_IMAGE_HEIGHT * FILLER_IMAGE_WIDTH;
    int totRed = 0, totGreen = 0, totBlue = 0;
    for (int i = 0; i < FILLER_IMAGE_HEIGHT; i++)
    {
        for (int j = 0; j < FILLER_IMAGE_WIDTH; j++)
        {
            totRed += pix[i][j].red;
            totGreen += pix[i][j].green;
            totBlue += pix[i][j].blue;
        }
    }
    averageColor.red = totRed / area;
    averageColor.green = totGreen / area;
    averageColor.blue = totBlue / area;
}
pixel fillerImage::getAverageColor() //return the average color
{
    return this->averageColor;
}
int fillerImage::getTimesUsed() //return how many times this fillerimage has been used
{
    return this->timesUsed;
}
void fillerImage::setTimesUsed(int used) //assign "used" to timesUsed
{
    this->timesUsed = used;
}

填充节点结构:

struct fillerNode{
    fillerImage *data;
    fillerNode *pre;
    fillerNode *next;
};

图像类标头:

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 object 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
};

错误是我创建了源图像的副本,然后尝试从空副本中获取像素,因此我创建了另一个 2D 像素数组并在那里获取像素,并相应地使用每个数组。

pixel** myPix = displayed->getPixels();
int height = displayed->getHeight();
int width = displayed->getWidth();
image* temp = new image;
temp->createNewImage(displayed->getWidth() / blockWidth, displayed->getHeight() / blockHeight);
pixel** shrinkPix = temp->getPixels();

for (int i = 0; i < displayed->getHeight() / blockHeight; i++)
{
    for (int j = 0; j < displayed->getWidth() / blockWidth; j++)
    {
        for (int k = 0; k < blockHeight; k++)
        {
            for (int m = 0; m < blockWidth; m++)
            {
                avgRed = avgRed + myPix[i * blockHeight + k][j * blockWidth + m].red;
                avgGreen = avgGreen + myPix[i * blockHeight + k][j * blockWidth + m].green;
                avgBlue = avgBlue + myPix[i * blockHeight + k][j * blockWidth + m].blue;
            }
        }
        avgRed = avgRed / blockSize;
        avgGreen = avgGreen / blockSize;
        avgBlue = avgBlue / blockSize;
        shrinkPix[i][j].red = avgRed;
        shrinkPix[i][j].green = avgGreen;
        shrinkPix[i][j].blue = avgBlue;
        avgRed = 0;
        avgGreen = 0;
        avgBlue = 0;
    }
}
for (int i = 0; i < displayed->getHeight(); i++)
{
    for (int j = 0; j < displayed->getWidth(); j++)
    {
        if ((i > displayed->getHeight() / blockHeight) || (j > displayed->getWidth() / blockWidth))
        {
            myPix[i][j].red = 0;
            myPix[i][j].green = 0;
            myPix[i][j].blue = 0;
        }
    }
}