代码改变世界

将内存图像数据封装成QImage V2

2014-03-06 14:00  江湖么名  阅读(878)  评论(0编辑  收藏  举报

转:http://www.cnblogs.com/bibei1234/p/3161555.html

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

当采用Qt开发相机数据采集软件时,势必会遇到采集内存图像并进行处理(如缩放、旋转)操作。如果能够将内存图像数据封装成QImage,则可以利用QImage强大的图像处理功能来进行图像处理,并能很好的进行显示。
在内存中,8bit灰度图像的宽度有可能不能满足BMP格式需求(为4的倍数),在封装成8bit灰度QImage时,会遇到封装不完整或错误的问题。本人总结了该问题,写了一个封装内存8bit灰度图像数据的C++类。

首先看代码部分:

//BufferToQImage.h

/* 
* Copyright (c) 2013,中科院苏州医工所 
* All rights reserved. 
*  
* 文件名称:BufferToQImage.h 
* 文件标识:见配置管理计划书 
* 摘    要:将内存数据封装成QImage。
*  
* 当前版本: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. 
*  
* 文件名称:BufferToQImage.h 
* 文件标识:见配置管理计划书 
* 摘    要:将内存数据封装成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放大显示,效果如下: