MFC关于JPG图片显示处理的几个方式

22 篇文章 1 订阅
12 篇文章 1 订阅

做远程视频监控项目,接触较多图片处理方面问题,作为学习做以下记录:

一、截图默认bmp格式转jpg压缩。

采用jpglib库去实现。

二、jpg图片接收后MFC显示(四种方式)

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

第一种:用流对象加载。

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图片

下面的代码则是用IPicture接口的方式来加载jpg图片(全屏显示图片)。
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);
}

}

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文件再加载,

1.在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;

}

5.显示

CWnd *pWnd;

pWnd = GetDlgItem(IDC_DISPLAY_WINDOW_STATIC);

CDC *pDC = pWnd->GetDC():

HDC hDC = pDC->m_hDC;

HDC memDC = CreateCompatibleDC(hDC);

SelectObject(memDC, hBitMap):

BitBlt(hDC, 0, 0,  1440, 900, memDC, 0, 0, SRCCOPY);

DeleteObject(hBitMap);

DeleteDC(memDC);

第四种方式:CImage

CWnd* pWnd;
pWnd=GetDlgItem(IDC_IMAGE1);
CDC* pDC=pWnd->GetDC();
HDC hDC = pDC->m_hDC;

CRect rect_frame;
CImage image;
pWnd->GetClientRect(&rect_frame);
image.Load(fileName);


::SetStretchBltMode(hDC,HALFTONE);
::SetBrushOrgEx(hDC,0,0,NULL);

image.Draw(hDC,rect_frame);
ReleaseDC(pDC);//释放picture控件的DC

在MFC窗口测试前面两种在固定大小窗口显示图片失真严重(在jpg指定1440*900窗口显示正常),第三种显示清晰度可以但是显示图片不全。

第四种方式显示正常。
 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 MFC显示 jpg 图片可以通过以下步骤实现: 首先,需要在 MFC 应用程序中添加一个 Picture Control 控件,用于显示图片。 接下来,需要导入相关的头文件,包括 "afx.h" 和 "afxwin.h"。 然后,在应用程序的消息映射中,添加一个响应 Picture Control 控件更新消息的处理函数。 在该处理函数中,可以使用 MFC 提供的 CImage 类来加载和显示 jpg 图片。可以使用 CImage 的 Load() 函数加载指定路径的 jpg 图片。例如,可以使用类似下面的代码加载图片: CImage image; image.Load(_T("路径/图片名.jpg")); 然后,可以使用 Picture Control 控件的 SetBitmap() 函数将加载的图片设置为要显示的位图。例如,可以使用下面的代码将图片设置为 Picture Control 控件的位图: m_pictureControl.SetBitmap(image.Detach()); 最后,应该确保在程序退出时,释放图片资源,可以在析构函数或销毁 Picture Control 控件的处理函数中调用 CImage 的 Destroy() 函数释放图片资源: image.Destroy(); 通过以上步骤,就可以在 MFC 应用程序中成功显示 jpg 图片了。 ### 回答2: 在MFC显示JPG图片需要使用GDI+库。 首先,需要添加GDI+的头文件和库文件: ``` #include <gdiplus.h> #pragma comment(lib,"gdiplus.lib") using namespace Gdiplus; ``` 然后,在MFC的窗口类中重写OnPaint函数用于绘制图片: ``` void CYourWndClass::OnPaint() { CPaintDC dc(this); GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); Graphics graphics(dc.GetSafeHdc()); Image image(L"your_image.jpg"); // 替换为图片路径和名称 graphics.DrawImage(&image, 0, 0, image.GetWidth(), image.GetHeight()); GdiplusShutdown(gdiplusToken); } ``` 上述代码中,使用`Image`类加载JPG图片,并使用`Graphics`类的`DrawImage`函数将图片绘制到窗口上。 最后,在窗口的初始化函数(如OnInitDialog)中调用Invalidate函数来触发窗口的重绘: ``` BOOL CYourWndClass::OnInitDialog() { CDialog::OnInitDialog(); Invalidate(); return TRUE; } ``` 以上就是使用MFC显示JPG图片的基本步骤。如果想要在其他控件中显示图片,可以在对应的控件绘制函数中使用相同的方法来绘制图片。 ### 回答3: 在MFC中,我们可以使用CImage类来显示jpg图片。 首先,需要在程序中引入相关的头文件和库,包括atlimage.h和comdef.h。 然后,我们可以创建一个CImage对象,并调用其Load函数加载jpg图片文件。例如,假设我们有一个名为image.jpgjpg图片文件,可以使用以下代码加载该图片: CImage image; image.Load(_T("image.jpg")); 接下来,我们需要将CImage对象中的图片绘制到显示窗口上。可以使用CDC类的相关函数来实现绘制操作。 首先,需要获取显示窗口的CDC对象。一种常见的方法是在窗口类中重写OnPaint函数,然后在该函数中获取CDC对象。例如: void CMyWindow::OnPaint() { CPaintDC dc(this); // 获取窗口的DC对象 // 在这里进行绘制操作 } 然后,在获取到CDC对象后,可以使用CDC的相关函数来绘制CImage对象中的图片。例如,可以使用CDC的BitBlt函数来实现简的绘制操作。以下是一个示例代码: void CMyWindow::OnPaint() { CPaintDC dc(this); // 获取窗口的DC对象 // 绘制CImage对象中的图片 int width = image.GetWidth(); int height = image.GetHeight(); image.BitBlt(dc.GetSafeHdc(), 0, 0, width, height, 0, 0, SRCCOPY); } 在上述示例代码中,我们首先获取了CImage对象的宽度和高度,并使用CDC的BitBlt函数将CImage对象中的图片绘制到窗口的DC对象上。 以上是一种简的在MFC显示jpg图片的方法。当然,还有其他多种方式可以实现此功能,具体的方法可以根据实际需求进行选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值