我目前正在使用阵列存储来自宽度为120像素,高度为100像素的24位BITMAP图像的R,G,B值进行成像处理。
正在使用Visual Studio 2010。

我目前已从24位位图中将各个R,G,B值提取到三个单独的2D数组中(假定正确的R,G,B值也已被写入具有正确像素数的文本文件中,因此被认为是正确的) 。

这些单独的R,G,B值需要还原回一个数组(1D或2D),然后将其写入图像文件。输出应与原始图像相同。

我尝试了以下操作,但是输出当前不正确(宽度,高度和内存大小相同,但颜色不正确)。

感谢您的指导和反馈。

#include <iostream>
#include <fstream>
#include <windows.h>
#include <WinGDI.h>

unsigned char** Allocate2DArray(int w, int h)
{
     unsigned char ** buffer = new unsigned char * [h];  // allocate the rows

     unsigned char * memory_pool = new unsigned char [w*h];  // allocate memory pool
     for (int i = 0; i < h; ++i)
     {
         buffer[i] = memory_pool;   // point row pointer
         memory_pool += w;          // go to next row in memory pool
     }
     return buffer;
}

void DeAllocate2DArray(unsigned char** buffer)
{
    delete [] buffer[0];  // delete the memory pool
    delete [] buffer;     // delete the row pointers
}



using namespace std;

int main()
{

const int width = 120;
const int height = 100;

    int bytesPerPixel = 3;
    unsigned char m_cHeaderData[54];
    unsigned char** m_cImageData = new unsigned char* [height];

    for( int i = 0; i <height; i++)
    {
        m_cImageData[i] = new unsigned char [width*bytesPerPixel];
    }

    ifstream* m_pInFile;
    m_pInFile = new ifstream;
    m_pInFile->open("image.bmp", ios::in | ios::binary);
    m_pInFile->seekg(0, ios::beg);
    m_pInFile->read(reinterpret_cast<char*>(m_cHeaderData), 54);
    for(int i = 0; i <height; i++)
    {
        m_pInFile->read(reinterpret_cast<char*>(m_cImageData[i]), width*bytesPerPixel);

    }

    m_pInFile->close();


    // Declare a pointer of the type you want.
    // This will point to the 1D array
    unsigned char* array_1D;
    array_1D = new unsigned char[height*width*bytesPerPixel];
    if(array_1D == NULL) return 0;  // return if memory not allocated

    // Copy contents from the existing 2D array
    int offset = 0;

    for(int j=0; j<height; j++)  // traverse height (or rows)
    {
        offset = width * bytesPerPixel* j;
        for(int i=0; i<width*bytesPerPixel; i++) // traverse width
        {
            array_1D[offset + i] = m_cImageData[j][i];
                     // update value at current (i, j)

        }
    }


    // Declare three 2D arrays to store R,G, and B planes of image.
    unsigned char**arrayR_2D, **arrayG_2D, **arrayB_2D;
    arrayR_2D = Allocate2DArray(width, height);
    arrayG_2D = Allocate2DArray(width, height);
    arrayB_2D = Allocate2DArray(width, height);

    // return if memory not allocated
    if(arrayR_2D == NULL || arrayG_2D == NULL || arrayB_2D == NULL) return 0;


    // Extract R,G,B planes from the existing composite 1D array
    ofstream RGBdata2D;
    RGBdata2D.open("RGBdata2D.txt");
    int pixelCount = 0;
    int offsetx = 0;
    int counter = 0;

    for(int j=0; j<height; j++)  // traverse height (or rows)
    {
        offsetx = width * j * bytesPerPixel;
        for(int i=0; i<width*bytesPerPixel; i+=bytesPerPixel) // width
        {
            arrayB_2D[j][counter] = array_1D[offsetx + i+0];
            arrayG_2D[j][counter] = array_1D[offsetx + i+1];
            arrayR_2D[j][counter] = array_1D[offsetx + i+2];

         RGBdata2D<<"B: "<< (int)arrayB_2D[j][counter] << " G: " << (int)arrayG_2D[j][counter] << " R: " << (int)arrayR_2D[j][counter]<< endl;
        pixelCount++;

        ++counter;
        }

        counter = 0;
    }

    RGBdata2D<<"count of pixels: "<< pixelCount << endl;
    RGBdata2D.close();


       //put RGB from 2D array contents back into a 1D array
    offset = 0;
    counter = 0;
    for(int j=0; j<height; j++)  // traverse height (or rows)
    {
        offset = width * bytesPerPixel * j;
        for(int i=0; i<width*bytesPerPixel; i+=bytesPerPixel) // width
        {
            array_1D[offset + i+0] = arrayB_2D[j][counter++];
            array_1D[offset + i+1] = arrayG_2D[j][counter++];
            array_1D[offset + i+2] = arrayR_2D[j][counter++];

        }
        counter = 0;
    }

    ofstream* m_pOutFileRGB;
    m_pOutFileRGB = new ofstream;
    m_pOutFileRGB->open("imageCopyRGB.bmp", ios::out | ios::trunc | ios::binary);
    m_pOutFileRGB->write(reinterpret_cast<char*>(m_cHeaderData), 54);
    for(int i = 0; i <height; i++)
    {
        m_pOutFileRGB->write(reinterpret_cast<char*>(array_1D), width*bytesPerPixel);

    }

    m_pOutFileRGB->close();



    // After complete usage, delete the memory dynamically allocated
    DeAllocate2DArray(arrayR_2D);
    DeAllocate2DArray(arrayG_2D);
    DeAllocate2DArray(arrayB_2D);


    // After complete usage, delete the memory dynamically allocated
    delete[] array_1D; //delete the pointer to pointer


    for(int i = 0; i <height; i++)
    {
        delete[] m_cImageData[i];
    }
    delete[] m_cImageData;


    system("pause");

    return 0;
}

最佳答案

我没有自己测试,但是在这一点上

for(int i=0; i<width*bytesPerPixel; i+=bytesPerPixel) // width
{
    array_1D[offset + i+0] = arrayB_2D[j][counter++];
    array_1D[offset + i+1] = arrayG_2D[j][counter++];
    array_1D[offset + i+2] = arrayR_2D[j][counter++];

}


您增加counter的次数过多,可能会导致错误的结果。
相反,请尝试以下操作:

for(int i=0; i<width*bytesPerPixel; i+=bytesPerPixel) // width
{
    array_1D[offset + i+0] = arrayB_2D[j][counter];
    array_1D[offset + i+1] = arrayG_2D[j][counter];
    array_1D[offset + i+2] = arrayR_2D[j][counter];
    counter++;
}

10-05 22:02