您的位置:首页 > 其它

vc加载jpg图片的方法

2011-10-24 20:18 363 查看
本文转自:http://www.cppblog.com/zhangyq/archive/2008/06/26/46816.html

MFC提供的CWnd只有默认加载BMP文件的接口,对JPG等图像是不支持的,而实际中经常需要用到非BMP的图片,在VC中加载.JPG格式的图片,有两种方法,用流对象加载和用IPicture接口加载。


IPicture
*m_picture;


OLE_XSIZE_HIMETRIC m_width;


OLE_YSIZE_HIMETRIC m_height;




CString m_filename("D:\\009.jpg");//文件名




CFile m_file(m_filename,CFile::modeRead );




//获取文件长度


DWORD m_filelen
= m_file.GetLength();




//在堆上分配空间


HGLOBAL m_hglobal
= GlobalAlloc(GMEM_MOVEABLE,m_filelen);




LPVOID pvdata
= NULL;


//锁定堆空间,获取指向堆空间的指针


pvdata
= GlobalLock(m_hglobal);




//将文件数据读区到堆中


m_file.ReadHuge(pvdata,m_filelen);




IStream* m_stream;




GlobalUnlock(m_hglobal);




//在堆中创建流对象


CreateStreamOnHGlobal(m_hglobal,TRUE,&m_stream);




//利用流加载图像


OleLoadPicture(m_stream,m_filelen,TRUE,IID_IPicture,(LPVOID*)&m_picture);




m_picture->get_Width(&m_width);


m_picture->get_Height(&m_height);




CDC* dc
= GetDC();




m_IsShow
= TRUE;


CRect rect;


GetClientRect(rect);


SetScrollRange(SB_VERT,0,(int)(m_height/26.45)-rect.Height());


SetScrollRange(SB_HORZ,0,(int)(m_width/26.45)-rect.Width());




m_picture->Render(*dc,1,50,(int)(m_width/26.45),(int)(m_height/26.45),0,m_height,m_width,-m_height,NULL);

以上代码是用创建流文件的方式加载,也可以加载.gif图片,但不能显示动画效果。

下面的代码则是用IPicture接口的方式来加载jpg图片(全屏显示图片)。

注意:这两段代码不能用在wince平台上,在wince上加载有另外的函数。


CString szFileName;


szFileName.Empty();


szFileName
= "D:\\84.jpg";




IStream
*pStm;


CFileStatus fstatus;


CFile file;



LONG cb;





if (file.Open(szFileName,CFile::modeRead)
&& file.GetStatus(szFileName,fstatus)
&& ((cb
= fstatus.m_size) !=
-1))


{


HGLOBAL hGlobal
= GlobalAlloc(GMEM_MOVEABLE,cb);


LPVOID pvData
=NULL;



if (hGlobal !=
NULL)


{


pvData
= GlobalLock(hGlobal);



if (pvData !=
NULL)


{


file.ReadHuge(pvData,cb);


GlobalUnlock(hGlobal);


CreateStreamOnHGlobal(hGlobal,TRUE,&pStm);


}


}


}







// HRESULT Render( HDC hdc,
//渲染图像用的设备环境句柄



// long x,
//在hdc上的水平坐标



// long y,
//在hdc上的垂直坐标



// long cx,
//图像宽度



// long cy,
//图像高度



// OLE_XPOS_HIMETRIC xSrc,
//在源图像上的水平偏移



// OLE_YPOS_HIMETRIC ySrc,
//在源图像上的垂直偏移



// OLE_XSIZE_HIMETRIC cxSrc,//在源图像上水平拷贝的数量



// OLE_YSIZE_HIMETRIC cySrc,//在源图像上垂直拷贝的数量



// LPCRECT prcWBounds
//指向目标图元设备环境句柄的指针);


CComQIPtr<IPicture> m_picture;


HRESULT hr
= OleLoadPicture(pStm,0,false,IID_IPicture,(void**)&m_picture);



long a,b;


m_picture->get_Width(&a);


m_picture->get_Height(&b);


CSize sz(a,b);


CDC
*pdc
= GetDlgItem(IDC_STATIC)->GetDC();



// CDC
*pdc = GetDC();



// pdc->HIMETRICtoDP(&sz);


CRect rect;


GetClientRect(rect);



// GetDlgItem(IDC_STATIC)->GetClientRect(&rect);


m_picture->Render(*pdc,0,0,sz.cx,sz.cy,0,b,a,-b,&rect);


m_picture->Render(*pdc,rect.left,rect.top,rect.Width(),


rect.Height(),0,b,a,-b,&rect);

也可以用GDI+把图片转成.bmp文件再加载,在StdAfx.h中静态调用gdiplus.lib,即由编译系统完成对DLL的加载,应用程序结束时卸载DLL的编码。如下:

#ifndef ULONG_PTR

#define ULONG_PTR unsigned long*

#include "GdiPlus.h"

using namespace Gdiplus;

#pragma comment(lib, "gdiplus.lib")

#endif

2、在类的头文件中定义,以下成员变量,用来初始化GDI+的使用和结束使用。

GdiplusStartupInput m_gdiplusStartupInput;

ULONG_PTR m_gdiplusToken;

3、在初始化函数中,初始化GDI+。如:在OnCreate()函数中加入初始化GDI+的函数:

GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);

4、对应的在OnDestroy()函数中加入结束GDI+使用的函数:

GdiplusShutdown(m_gdiplusToken);

接着,就可以使用GDI+了,要实现要求的内容很容易,方法如下:

写一个如下的方法:

HBITMAP ReturnHBITMAP(CString FileName)//FileName可能是bmp、dib、png、gif、jpeg/jpg、tiff、emf等文件的文件名

{

Bitmap tempBmp(FileName.AllocSysString()) ;

Color backColor;

HBITMAP HBitmap;

tempBmp.GetHBITMAP(backColor,&HBitmap);

return HBitmap;

}

在WM5.0+VC8.0的环境下,还可以COM(组件)的方式加载图片,这种方法能加载的图片的格式比较全(.jpg,.png,.gif),在Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Samples\CPP\Win32\Imaging例子中,用这个COM可以加载皮肤,有兴趣的朋友可以试一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: