图片文件的存在形式并不总是文件形式,有时可能是内存块、也有可能是字节流,比如保存于数据库中的某一图片,用GetChunk方法读取出来后一般保存在一个预先分配的内存块中,我们知道内存块的首地址,内存块的大小,要把这样的图片显示出来,可以自己编写函数按文件结构解析数据,但未免太麻烦,也是没有意义的“制造轮子”的重复工作,不如用windows系统自带的Ipicture的COM组件显示图片来得更简便些。下面是核心代码。技巧是把数据内存块转换成一个内存文件CMemFile,不必把图片文件存储成一个临时文件再读取。
1 #include <atlbase.h>
2 #include <afxpriv2.h>
3 void CIpicDlg::ShowPic()
4 {
5 CComQIPtr<IPicture>spIPicture;
6 HRESULT m_hr;
7 //unsigned char* pPictureData;
8 //UINT nPictureSize;
9 CRect rc;
10 m_wndPic1.GetClientRect(&rc);
11 CDC* pDC = m_wndPic1.GetDC();
12 if(m_pPictureData)
13 {
14 CMemFile memfile;
15 memfile.Attach(m_pPictureData,m_nPictureSize);
16 CArchive ar(&memfile, CArchive::load | CArchive::bNoFlushOnDelete);
17 CArchiveStream arcstream(&ar);
18 HRESULT hr = OleLoadPicture((IStream*)&arcstream, 0, FALSE,
19 IID_IPicture, (void**)&spIPicture);
20 ASSERT(SUCCEEDED(hr) && spIPicture);
21 OLE_XSIZE_HIMETRIC hmWidth = 0;
22 OLE_YSIZE_HIMETRIC hmHeight = 0;
23 m_hr = spIPicture->get_Width(&hmWidth);
24 ASSERT(SUCCEEDED(m_hr));
25 m_hr = spIPicture->get_Height(&hmHeight);
26 ASSERT(SUCCEEDED(m_hr));
27 spIPicture->Render(pDC->m_hDC, rc.left, rc.top, rc.Width(), rc.Height(),
28 0, hmHeight, hmWidth, -hmHeight, NULL);
29 CSize sz(hmWidth,hmHeight);
30 pDC->HIMETRICtoDP(&sz);
31 }
32 if (spIPicture)
33 {
34 spIPicture.Release();
35 }
36 }
///////////////////////////////////////////////////////////////////////////////////////////////////
图片文件的存在形式并不总是文件形式,有时可能是内存块、也有可能是字节流,比如保存于数据库中的某一图片,用GetChunk方法读取出来后一般保存在一个预先分配的内存块中,我们知道内存块的首地址,内存块的大小,要把这样的图片显示出来,可以自己编写函数按文件结构解析数据,但未免太麻烦,也是没有意义的“制造轮子”的重复工作,不如用windows系统自带的Ipicture的COM组件显示图片来得更简便些。下面是核心代码。技巧是把数据内存块转换成一个内存文件CMemFile,不必把图片文件存储成一个临时文件再读取。
1 #include <atlbase.h>
3 void CIpicDlg::ShowPic()
4 {
5 CComQIPtr<IPicture>spIPicture;
6 HRESULT m_hr;
7 //unsigned char* pPictureData;
8 //UINT nPictureSize;
9 CRect rc;
10 m_wndPic1.GetClientRect(&rc);
11 CDC* pDC = m_wndPic1.GetDC();
12 if(m_pPictureData)
13 {
14 CMemFile memfile;
15 memfile.Attach(m_pPictureData,m_nPictureSize);
16 CArchive ar(&memfile, CArchive::load | CArchive::bNoFlushOnDelete);
17 CArchiveStream arcstream(&ar);
18 HRESULT hr = OleLoadPicture((IStream*)&arcstream, 0, FALSE,
19 IID_IPicture, (void**)&spIPicture);
20 ASSERT(SUCCEEDED(hr) && spIPicture);
21 OLE_XSIZE_HIMETRIC hmWidth = 0;
22 OLE_YSIZE_HIMETRIC hmHeight = 0;
23 m_hr = spIPicture->get_Width(&hmWidth);
24 ASSERT(SUCCEEDED(m_hr));
25 m_hr = spIPicture->get_Height(&hmHeight);
26 ASSERT(SUCCEEDED(m_hr));
27 spIPicture->Render(pDC->m_hDC, rc.left, rc.top, rc.Width(), rc.Height(),
28 0, hmHeight, hmWidth, -hmHeight, NULL);
29 CSize sz(hmWidth,hmHeight);
30 pDC->HIMETRICtoDP(&sz);
31 }
32 if (spIPicture)
33 {
34 spIPicture.Release();
35 }
36 }
显示内存中的BMP
//把BMP文件读到内存中 bmpbuf
void CAskProxyDlg::OnButton3()
{
// TODO: Add your control notification handler code here
CFile pfile;
pfile.Open("d:\\22.bmp",CFile::modeRead);
int ll = pfile.GetLength();
pfile.Read(bmpbuf,ll);
ShowBmp();
// PostDecHandler((BYTE*)bmpbuf + 0x436,0,0);
pfile.Close();
}
//显示内存中的BMP
void CAskProxyDlg::ShowBmp()
{
CClientDC dc(this);//取得客户区内存DC
CString cs;
int index(0);
BITMAPFILEHEADER *pfilehead = (BITMAPFILEHEADER*)bmpbuf;
index = sizeof(BITMAPFILEHEADER);
BITMAPINFO *pbi = (BITMAPINFO*)(bmpbuf + index);//BITMAPINFOHEADER
int width = pbi->bmiHeader.biWidth;
int height = pbi->bmiHeader.biHeight;
int r = SetDIBitsToDevice(dc.m_hDC,100,100,width,height,0,0,0,height,bmpbuf+pfilehead->bfOffBits,pbi,DIB_RGB_COLORS);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
QImage类提供了一个硬件无关的图像表示方法,该图像可以逐像素被访问和用于画图设备。
Qt提供了QImage、QPixmap、QBitmap和QPicture四种图像操作类。QImage类主要用于I/O和直接逐像素访问、操作;QPixmap主要用于在屏幕中显示图像;QBitmap是一个基于方便考虑继承自QPixmap的提供1bit深度二值图像的类;QPicture是一个可以记录和响应QPainter类命令的画图设备。
QImage继承自QPaintDevice,QPainter类可以被用来直接在图像上进行画操作。
QImage类支持QImage::Format枚举变量描述的多种图像类型,包括8-bit, 32-bit 和 alpha-blended images
QImage 提供很多可以用于获取图像信息和进行图像变换的函数。
1。读写图像
QImage有多种读取图像的方法。图像文件可以在生成QImage对象的过程中或者在之后用load和loadFromData方法读取,也可以用静态方法fromData利用给定的数据构造。读取的图像可以是存储在磁盘中或某个嵌入式应用程序的资源。
save方法可以用来保存QImage对象。
2。图像信息
QImage类提供了很多用于获取图像信息的方法。
如size、width、height、dotsPerMeterX、dotsPerMeterY、pixel、text、depth
3。像素赋值操作
1).32-bit图像
用qRgb或qRgba方法设置一个颜色值,再用sexPixel将相应像素设置为相应颜色
2).8-bit和1-bit二值图像
每一个像素的值是color table List中的一个索引,因此像素的值只能被改成一个在color table List中已经定义的值。如果想往color table List中加入新的值,可以用setColor方法。
4。图像格式
QImage中的每一个像素由一个整数表示,这个整数的大小取决于不同的图像格式。
8-bit图像的每一个像素的值是color table List中的一个索引,32-bit每一个像素拥有一个自己的rgb值(RGB、ARGB、premultiplied ARGB)
图像的格式可以用format方法得到,convertToFormat方法可以用来将一种格式的图像转换为另外一种,allGray和isGrayscale方法可以用来检查一个彩色图像是否可以被安全转换为灰度图像。
5。图像变换
mirrored、scaled、rgbSwapped、scaledToWidth、scaledToHeight、transformed...