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

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

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

第一步:首先根据相机的SDK内的读图像函数,获取图像数据imgData、宽度imgWidth和高度imHeight。
第二步:申请QImage对象,注意类型是Format_RGB32.
第三步:利用成员函数setPixel()设置QImage像素。由于相机输出的图像是灰度图像,每一位置的R、G、B分量相等且均等于当前位置的像素值。

程序如下

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

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

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

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

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.

8位灰度图封装

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

首先看代码部分:BufferToQImage.h

/*
* 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

/*
* 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放大显示,效果如下

原文地址:https://www.cnblogs.com/flyinggod/p/8721266.html

时间: 2024-10-13 01:02:37

如何将内存图像数据封装成QImage的相关文章

MVC扩展ModelBinder,通过继承DefaultModelBinder把表单数据封装成类作为action参数

把视图省.市.街道表单数据,封装成一个类,作为action参数.如下: action方法参数类型: namespace MvcApplication1.Models{    public class Customer    {        public string Address { get; set; }    }} 在自定义ModelBinder中,接收视图表单数据,封装成Customer类. using System.Web; using System.Web.Mvc; using M

kinect2.0 基础篇第3篇 用C#在Visual Studio上编写把深度图像转换成彩色图像

本示例实现的功能有:有两个Radiobutton控件  选一个,点击启动按钮, 第一个是将深度图像转换成彩色图像 第二个是将深度图像做一些简单处理(例如太暗的调白一点) 涉及到一点遥感图像处理知识,将深度数据值转换为色调和饱和度 遥感图像处理那块不懂,有兴趣的自己可以研究研究,代码的基于kinect1的教程,慢慢尝试出来的,虽然功能实现了,但是原理还不是很懂 <Window x:Class="EnhancedDepthWPF.MainWindow" xmlns="htt

深度学习文章3:将自己的图像数据转换成caffe需要的db(leveldb/lmdb)文件

将自己的图像数据转换成caffe需要的db(leveldb/lmdb)文件 在搭建好caffe环境之后,我们往往需要对自己的图像数据进行训练/测试,我们的图像数据往往时图片文件,如jpg,jpeg,png等,然而在caffe中我们需要使用的数据类型是lmdb或leveldb,例如:在之前测试MNIST数据集< 深度学习文章2:使用MNIST数据集验证Caffe是否安装成功 >时,我们运行脚本create_mnist.sh就是生成对应的db文件,运行后在~/caffe/examples/mnis

OCR文字识别软件中怎么把图像转换成HTML

之前给大家介绍了使用OCR文字识别软件ABBYY FineReader Mac版将PDF转换成HTML文档(详见PDF转换成HTML文档首选ABBYY Mac),其实ABBYY FineReader无论Mac版还是Windows版都可以实现这一点,除此之外还可以将图像文件转换成HTML文档,本文具体讲讲这一功能. ABBYY FineReader是一款OCR图文识别软件,当前最新版本为ABBYY FineReader 12,可快速方便地将扫描纸质文档.PDF文件和数码相机的图像转换成可编辑.可搜

SpringMVC将通过ajax发送的 json数据封装成JavaBean

SpringMVC将通过ajax发送的 json数据封装成JavaBean 通过ajax发送的 json数据封装成JavaBean对发送时有如下要求: 1.发送的数据类型必须时UTF-8 2.发送的必须时JSON格式 3.JavaBean中的set方法中去掉set方法后首字母小写的属性名必须域JSON格式传过来的属性名称相同 第一步.前端界面 <button id="jsonBtn">发送json格式的utf-8数据</button> <script ty

使用jbc查询数据封装成对象的工具类

package com.briup.jdbctest; import java.lang.reflect.Field; import java.math.BigDecimal; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; impor

Image Stride(内存图像行跨度)

如果你用的是 MSDN Library For Visual Studio 2008 SP1,那么你应该能够在下面地址中找到这篇文章的原文: ms-help://MS.MSDNQTR.v90.chs/medfound/html/13cd1106-48b3-4522-ac09-8efbaab5c31d.htm 转载不需要指明出处,但是必须保持本文的完整性: ==================================================================== Wh

Caffe使用:如何将一维数据或其他非图像数据转换成lmdb

caffe事儿真多,数据必须得lmdb或者leveldb什么的才行,如果数据是图片的话,那用caffe自带的convert_image.cpp就行,但如果不是图片,就得自己写程序了.我也不是计算机专业的,我哪看得懂源码,遂奋发而百度之,然无甚结果,遂google之,尝闻“内事不决问百度,外事不决问google”,古人诚不我欺.在caffe的google group里我找到了这个网址:http://deepdish.io/2015/04/28/creating-lmdb-in-python/ 代码

将一副图像转换成油画

原创性声明:下面代码是本人改写自C#语言编写的软件改写自PhotoSprite (Version 3.0 .2006.由 联骏 编写).由使用OpenCV300编写. 先看一下效果 算法未作不论什么优化,优化算法能够看Photoshop 油画效果滤镜. 算法原理也不用细说了,源代码之前,了无秘密. 代码 cv::Mat OilPaint(cv::Mat I,int brushSize, int coarseness) { assert(!I.empty()); if (brushSize < 1