将RGB值写入BITMAP图像文件

时间:2015-10-12 13:32:24

标签: c++ image bitmap rgb

我目前正致力于使用数组进行成像处理,以存储宽度为120且高度为100像素的24位BITMAP图像的R,G,B值。 正在使用Visual Studio 2010。

我目前已将各个R,G,B值从24位位图中提取到三个独立的二维数组中(假设正确的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;
}

1 个答案:

答案 0 :(得分:1)

我自己没有测试,但此时

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