2015-10-12 2 views
0

В настоящее время я работаю над обработкой изображений с использованием массивов для хранения значений R, G, B из 24-битного изображения BITMAP шириной 120 и высотой 100 пикселей. Используется Visual Studio 2010.Запись значений RGB в файл изображения BITMAP

В настоящее время я выделил отдельные значения R, G, B на три отдельных массива2D из 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

я не проверял сам, но на данный момент

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

Спасибо за это предложение. Теперь я проверил и заметил, что правильные значения R, G, B записываются в массив_1D (тогда как изначально они не были). Мне все же нужно как-то правильно записать это в новый файл BITMAP. Все еще не дает правильного изображения. –

Смежные вопросы