QImage

QImage 是用于读写绘制图像的基本类库,显示图像,我们借助于QImage,重点是如何通过图像二维数组(或三维数组)构造一个QImage对象。

以下来至于QImage构造函数QImage::QImage(uchar *data, int width, int height, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr) http://doc.qt.io/qt-5/qimage.html#QImage-3

 
QImage::QImage(uchar *data, int width, int height, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr)
Constructs an image with the given width, height and format, that uses an existing memory buffer, data. The width and height must be specified in pixels, data must be 32-bit aligned, and each scanline of data in the image must also be 32-bit aligned.

The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer. The image does not delete the buffer at destruction. You can provide a function pointer cleanupFunction along with an extra pointer cleanupInfo that will be called when the last copy is destroyed.

If format is an indexed color format, the image color table is initially empty and must be sufficiently expanded with setColorCount() or setColorTable() before the image is used.

 

 

从构造函数中可以看出几个需要注意的地方:

    1. uchar* data 的对象需要保持持久性,即QImage图像并未深度拷贝data中的数据,仅仅只是一个指针应用。因此,构建QImage之后的,data不能delete,否则会出错。
    1. QImage::Format 在此处我们制定RGB888的格式,即图像为24位,RGB各占8位。
    1. data中的数据是如何排列的?简而言之,data中的数据是按BIP方式排列的,但有个要求,就是每一行的图像数据,要按4字节对齐。(重点在此)

 

 

 

QImage CRSImage::toQImage()
{
    //1. 为QImage准备一个Buffer,而且要求具有持久性,故而最佳的办法就是定义为CRSImage的成员变量
    //unsigned char*    m_pDataBuff;    
    
    //2. 图像Buffer的大小
    int        iImageHeight = m_lLines;    //图像的宽度
    
    // 此处略有点难以理解,这是因为QImage的图像数据是按BIP方式排列的,但有个要求,就是在每一行数据排列完毕之后,数据是否为4字节的整数倍。m_lSamples是图像的宽度,*24代表,RGBRGBRGB...这样排列下来,一行图像的bit数。此时,我们要判断24*m_lSamples是否为4字节(32bit)的整数倍,比如:24*m_lSamples 为72,就要变为96.
    int        iByteLines = (m_lSamples*24+31)/32*4;    //图像每一行的字节数
    
    // m_pDataBuff 的大小为 [m_lLines*iByteLines]

    //3. 准备QImage的Buffer
    int        i, j, m=0, n;
    for (i=0; i<m_lLines; i++)    //行遍历
    {
        for (j=0; j<m_lSamples; j++)    //列遍历
        {
            m_pDataBuff[m++] = m_pppData[Red][i][j];    //R波段
            m_pDataBuff[m++] = m_pppData[Grn][i][j];    //G波段
            m_pDataBuff[m++] = m_pppData[Blu][i][j];    //B波段
        }
        
        // 1行数据填充完毕之后,我们要检查m是否为4字节的整数倍,可以写为:
        while(k%4) {k++;}    //还有一种写法 while(k%iByteLines) {k++;}
    }
    
    // 构造一个对象,返回
    return QImage(m_pDataBuff, m_lSamples, m_lLines, QImage::Format_RGB888);
}

 

 

 

 

 

 

来自:https://github.com/cugwhp/OOPCPP/issues/10

##############################

posted @ 2022-12-23 21:25  西北逍遥  阅读(1040)  评论(0编辑  收藏  举报