Benjamin

静以修身,俭以养德,非澹薄无以明志,非宁静无以致远。
随笔 - 276, 文章 - 0, 评论 - 196, 引用 - 0
数据加载中……

vc加载jpg图片的方法

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可以加载皮肤,有兴趣的朋友可以试一下。

posted on 2008-04-11 11:04 Benjamin 阅读(9978) 评论(4)  编辑 收藏 引用 所属分类: VC

评论

# re: vc加载jpg图片的方法  回复  更多评论   

你好,我现在是在winCE上加载JPG图片,图片是一段内存中的BUFF,就是一个流,但是winCE不支持//利用流加载图像OleLoadPicture函数,卡在这里
,请教楼主有什么办法可以实现啊
2008-06-26 11:32 | ty--90

# re: vc加载jpg图片的方法  回复  更多评论   

@ty--90
CBitmap类的Attach方法加载.jpg图像,它的参数就是一个文件路径,这个是专门针对EVC用的一个函数。具体的用法可以参照MSDN
2008-06-28 16:08 | Herb

# re: vc加载jpg图片的方法[未登录]  回复  更多评论   

你好,有两个问题,第一个是,在第一段代码中,m_IsShow = TRUE;
是什么意思?这是什么类型的变量,还是控件声明的变量.
第二个问题,是第二段代码中,CComQIPtr<IPicture> m_picture;
是什么意思?使用它需要加载什么文件,我用的时候它出现未定义的错误,请问,怎么定义它?
2009-04-09 11:13 | sky

# re: vc加载jpg图片的方法  回复  更多评论   

m_IsShow和图片加载无关。
CComQIPtr<IPicture> m_picture,它用的是ATL中的智能指针。要加头文件
atlbase.h
2009-04-11 14:10 | Herb

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理