如何将内存图像数据封装成QImage

博客转载自:https://blog.csdn.net/lg1259156776/article/details/52318638

当采用Qt开发相机数据采集软件时,势必会遇到采集内存图像并进行处理(如缩放、旋转)操作。如果能够将内存图像数据封装成QImage,则可以利用QImage强大的图像处理功能来进行图像处理,并能很好的进行显示。下面以灰度相机为例,介绍封装方法:

1

2

3

第一步:首先根据相机的SDK内的读图像函数,获取图像数据imgData、宽度imgWidth和高度imHeight。

第二步:申请QImage对象,注意类型是Format_RGB32.

第三步:利用成员函数setPixel()设置QImage像素。由于相机输出的图像是灰度图像,每一位置的R、G、B分量相等且均等于当前位置的像素值。

程序如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

QImage desImage = QImage(imgWidth,imgHeight,QImage::Format_RGB32); //RGB32 

   

//RGB分量值 

int b = 0; 

int g = 0; 

int r = 0;  

   

//设置像素 

for (int i=0;i<imgHeight;i++) 

    for (int j=0;j<imgWidth;j++) 

    

        b = (int)*(imgDataNew+i*imgWidth+j); 

        g = b; 

        r = g; 

        desImage.setPixel(j,i,qRgb(r,g,b)); 

    

}

对于灰度图像数据,如下封装方式是错误的。

1

QImage desImage = QImage(imgData, imgWidth, imgHeight, QImage::Format_Indexed8)

原因是QImage的构造函数中写道:

1

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 <br>aligned, and each scanline of data in the image must also be 32-bit aligned.

8位灰度图封装

在内存中,8bit灰度图像的宽度有可能不能满足BMP格式需求(为4的倍数),在封装成8bit灰度QImage时,会遇到封装不完整或错误的问题。本人总结了该问题,写了一个封装内存8bit灰度图像数据的C++类

首先看代码部分:BufferToQImage.h

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

/* 

* Copyright (c) 2013,中科院苏州医工所 

* All rights reserved. 

*  

* 当前版本:1.0 

* 作    者:LYC

* 完成日期:2013年6月27日 

*/ 

   

#ifndef BUFFERTOQIMAGE_H 

#define BUFFERTOQIMAGE_H 

   

#include <QImage> 

#include <Windows.h> 

#include <assert.h> 

#include <QVector> 

   

class BufferToQImage 

public

    BufferToQImage(void); 

    ~BufferToQImage(void); 

   

public

    QImage Pk8bitGrayToQIm(const BYTE *pBuffer, const int &bufWidth, const int &bufHight); //将8bit灰度数据封装成QImage 

   

private

    QVector<QRgb> vcolorTable; //生成灰度颜色表 

   

}; 

   

#endif 

//BufferToQImage.cpp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

/* 

* Copyright (c) 2013,中科院苏州医工所 

* All rights reserved. 

*  

* 摘    要:将内存数据封装成QImage。

*  

* 当前版本:1.0 

* 作    者:LYC

* 完成日期:2013年6月27日 

*/ 

   

#include "BufferToQImage.h" 

   

BufferToQImage::BufferToQImage(void

    for (int i = 0; i < 256; i++) 

    

        vcolorTable.append(qRgb(i, i, i)); 

    

   

BufferToQImage::~BufferToQImage(void

   

   

/*

* 函数名:Pk8bitGrayToQIm()

* 功能:将8bit灰度数据封装成QImage

* 参数:

*   pBuffer - 内存数据指针

*   bufWidth - 内存数据宽度

*   bufHight - 内存数据高度

* 返回值:QImage

* 作者:LYC

* 时间:2013.6.27

*/ 

QImage BufferToQImage::Pk8bitGrayToQIm(const BYTE *pBuffer, const int &bufWidth, const int &bufHight) 

    //对参数的有效性进行检查 

    assert((pBuffer != NULL) && (bufWidth>0) && (bufHight>0)); 

   

    int biBitCount = 8; //灰度图像像素bit数 

    int lineByte = (bufWidth * biBitCount/8 + 3) / 4 * 4; //bmp行byte数(格式宽度,为4的倍数) 

   

    if (bufWidth == lineByte) //判断图像宽度与格式宽度 

    

        QImage qIm = QImage(pBuffer, bufWidth, bufHight, QImage::Format_Indexed8);  //封装QImage 

        qIm.setColorTable(vcolorTable); //设置颜色表 

   

        return qIm;  

    

    else 

    

        BYTE *qImageBuffer = new BYTE[lineByte * bufHight]; //分配内存空间 

        uchar *QImagePtr = qImageBuffer; 

   

        for (int i = 0; i < bufHight; i++) //Copy line by line 

        

            memcpy(QImagePtr, pBuffer, bufWidth); 

            QImagePtr += lineByte; 

            pBuffer += bufWidth; 

        }   

   

        QImage qImage = QImage(qImageBuffer, bufWidth, bufHight, QImage::Format_Indexed8);  //封装QImage 

        qImage.setColorTable(vcolorTable); //设置颜色表 

           

        return qImage; 

    

利用我的博客中**任意宽度灰度BMP图像读写 V2 ** 的程序,可以读取任意宽度的图像,选择能够返回有效图像数据的成员函数,可以模拟相机写入内存中的数据。我利用rd8BitBmpNtFmt()读取78*86的图像,利用上述成员函数将内存的图像数据封装成QImage,并原尺寸显示和512*512放大显示,效果如下

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的Qt widget封装的YUV数据显示类: ```cpp // yuvwidget.h #ifndef YUVWIDGET_H #define YUVWIDGET_H #include <QWidget> #include <QImage> class YUVWidget : public QWidget { Q_OBJECT public: explicit YUVWidget(QWidget *parent = nullptr); virtual ~YUVWidget(); void setYUVData(unsigned char *yuvData, int width, int height); protected: virtual void paintEvent(QPaintEvent *event); private: QImage m_image; unsigned char *m_yuvData; int m_width; int m_height; }; #endif // YUVWIDGET_H // yuvwidget.cpp #include "yuvwidget.h" #include <QPainter> YUVWidget::YUVWidget(QWidget *parent) : QWidget(parent), m_yuvData(nullptr), m_width(0), m_height(0) { } YUVWidget::~YUVWidget() { if (m_yuvData != nullptr) { delete [] m_yuvData; } } void YUVWidget::setYUVData(unsigned char *yuvData, int width, int height) { if (m_yuvData != nullptr) { delete [] m_yuvData; } m_yuvData = new unsigned char[width * height * 3 / 2]; memcpy(m_yuvData, yuvData, width * height * 3 / 2); m_width = width; m_height = height; m_image = QImage(m_yuvData, m_width, m_height, QImage::Format_YUV420P); m_image = m_image.rgbSwapped(); update(); } void YUVWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.drawImage(QPoint(0, 0), m_image); } ``` 在这个类中,我们使用QImage来管理YUV数据内存并显示。在setYUVData函数中,我们首先使用new来分配足够的内存来存储YUV数据,并将其复制到新分配的内存中。然后使用QImage的构造函数来创建一个QImage对象,该对象指向我们刚刚分配的内存,格式为QImage::Format_YUV420P(这是默认格式,也可以根据需要选择其他格式)。最后,我们调用rgbSwapped函数来将图像颜色空间从YUV换为RGB,并更新窗口以显示图像。 在paintEvent函数中,我们使用QPainter来在窗口中绘制图像
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值