从位图图像中提取RGB值 [英] Extract RGB values from Bitmap Image

查看:95
本文介绍了从位图图像中提取RGB值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<小> 你好。我目前正在尝试从256色位图图像中提取R,G,B值(用于测试目的,固定宽度为152,高度为150)。我已经使用BITMAPINFOHEADER和BITMAPFILEHEADER检查了偏移量为1078,每像素字节数为1.



图像数据最初放入二维数组中,然后放入一维数组。分配了三个2维数组来保存每个像素的R,G,B值。



当我运行程序时,以下的Debug Assertion失败了!消息出现:

表达式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)



以下是代码,我会重视您的专家反馈以及如何修复此错误。



Hello. I am currently trying to extract R, G, B values from a 256 colour bitmap image (using for testing purposes a fixed width of 152 and height 150). I have checked using BITMAPINFOHEADER and BITMAPFILEHEADER that the offset is 1078 and bytes per pixel is 1.

The image data is initially placed in a 2 dimensional array before being placed into a 1 dimensional array. Three 2 dimensional arrays were allocated to hold the R, G, B values from each pixel.

When I run the program, the following Debug Assertion Failed! message appears:
Expression: _BLOCK_TYPE_IS_VALID (pHead->nBlockUse)

Below is the code and I would value your expert feedback and how to fix this error.

unsigned char** Allocate2DArray(unsigned char** buffer, int w, int h)
{
    buffer = new unsigned char*[h];
    if(buffer == NULL) return 0; // return if memory not allocated
    // For each of these pointers, allocate memory of size ‘w’
    for(int j=0; j<h; j++)
    {   buffer[j] = new unsigned char[w];
        if(buffer[j] == NULL) return 0;// return if not allocated
    }
    return buffer;
}

void DeAllocate2DArray(unsigned char** buffer, int h)
{
    // After complete usage, delete the memory dynamically allocated
    for(int j=h-1; j>= 0; j--)
        delete[] buffer[j]; //delete rows
    delete[] buffer; //delete the pointer to pointer
}



using namespace std;

int main()
{
    ifstream image;
    image.open("image.bmp",std::ios_base::binary);

    if (image.is_open())
    {
        cout<< "function success\n";
    }
    else
    {
        cout<< "unable to open file";
    }


    const int width = 152;
    const int height = 150;

    unsigned char m_cHeaderData[1078];
    unsigned char** m_cImageData = new unsigned char* [height];

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

    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), 1078); 
    //bitmap bits start at offset 1078

    for(int i = 0; i <height; i++)
    {
       m_pInFile->read(reinterpret_cast<char*>(m_cImageData[i]), width);
    }

    m_pInFile->close();


    // Declare a pointer of the type you want.
    // This will point to the 1D array
    unsigned char* array_1D;

    // Now allocate memory for array_1D
    array_1D = new unsigned char[height*width];
    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 * j;
        for(int i=0; i<width; 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(arrayR_2D, width, height);
    arrayG_2D = Allocate2DArray(arrayG_2D, width, height);
    arrayB_2D = Allocate2DArray(arrayB_2D, 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
    int offsetx = 0;
    int counter = 0;
    int bytesPerPixel = 1;

    for(int j=0; j<height; j++)  // traverse height (or rows)
    {
        offset = width * j;
        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];
        }
        counter = 0;
    }


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

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

    //deallocate memory:
    delete m_pInFile;
    delete m_pOutFile;
    for(int i = 0; i <height; i++)
    {
        delete[] m_cImageData[i];
    }
    delete[] m_cImageData;


    system("pause");

    return 0;
}

推荐答案

错误在于:

The error is here:
//deallocate memory:
delete m_pInFile;
delete m_pOutFile;



m_pInFile m_pInFile 是流而不是内存指针。





正确答案应该是:

这些对象尚未使用 new 在堆上分配,但是位于堆栈上,因此无法销毁使用删除


m_pInFile and m_pInFile are streams and not memory pointers.


The correct answer should be:
These objects have not been allocated on the heap using new but are located on the stack and can't be therefore destroyed using delete.


这篇关于从位图图像中提取RGB值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆