应用CImage类用文件和流的方式显示图片和放大缩小图片

2024-03-23 16:18

本文主要是介绍应用CImage类用文件和流的方式显示图片和放大缩小图片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.是MFC工程
2.创建默认工程:单文档工程
3.工程名:JPEGTest
4.1在CJPEGTestView类中添加
HANDLE    m_hFile;
CImage m_Image;
void LoadMemImage( void *  pMemData,  long  len);
afx_msg void OnFileOpen();
4.2在stdafx.h中添加#include <atlimage.h>
4.3在CJPEGTestView.cpp中添加
BEGIN_MESSAGE_MAP(CJPEGTestView, CView)
ON_COMMAND(ID_FILE_OPEN,            &CJPEGTestView::OnFileOpen)//这个是添加的
END_MESSAGE_MAP()
4.4
void CJPEGTestView::OnFileOpen()
{
CString strFilter;
CSimpleArray<GUID> aguidFileTypes;
HRESULT hResult;

// 获取CImage支持的图像文件的过滤字符串
hResult = m_Image.GetExporterFilterString(strFilter,aguidFileTypes,
_T( "All Image Files") );
if ( FAILED(hResult) )
{
MessageBox(_T("GetExporterFilter调用失败!"));
return;
}
CFileDialog dlg( TRUE, NULL, NULL, OFN_FILEMUSTEXIST, strFilter );
if ( IDOK != dlg.DoModal() )
return;

m_Image.Destroy();

{
//在此处是用流的方式显示JPEG
m_hFile = ::CreateFile(dlg.GetFileName(),GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY,NULL); // 用这个函数比OpenFile好
if ( m_hFile == INVALID_HANDLE_VALUE)
{
MessageBox(_T("打开文件失败"));
CloseHandle( m_hFile ); // 一定注意在函数退出之前对句柄进行释放。
return;
}
DWORD filesize=GetFileSize( m_hFile,NULL );

char* buffer=new char[filesize+1]; // 最后一位为 '/0',C-Style 字符串的结束符。

DWORD readsize;
ReadFile( m_hFile,buffer,filesize,&readsize,NULL);

buffer[filesize]=0;

LoadMemImage(buffer,readsize);

delete[] buffer; // 注意是delete[] 而不是 delete
CloseHandle(m_hFile); // 关闭句柄。
}

// 设置主窗口标题栏内容
CString str;
str.LoadString(AFX_IDS_APP_TITLE);

AfxGetMainWnd()->SetWindowText(str + _T("_") + dlg.GetFileName());

Invalidate(); // 强制调用OnDraw
}
void CJPEGTestView::LoadMemImage( void *  pMemData,  long  len)
{
HGLOBAL hGlobal  GlobalAlloc(GMEM_MOVEABLE, len);

void *  pData  GlobalLock(hGlobal);

memcpy(pData, pMemData, len);

GlobalUnlock(hGlobal);

IStream *  pStream  NULL;
if  (CreateStreamOnHGlobal(hGlobal, TRUE,  & pStream)  ==  S_OK)
{
if ( FAILED( m_Image.Load(pStream)) )
{
MessageBox(_T("调用图像文件失败!"));
return;
}
pStream -> Release();
}
GlobalFree(hGlobal);
}
void CJPEGTestView::OnDraw(CDC* pDC)
{
CJPEGTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!m_Image.IsNull())
{
m_Image.Draw(pDC->m_hDC,0,0);
}
}
5.还可以添加放大缩小功能
在:CJPEGTestDoc类中添加:
public:
inline float GetZoomFactor() { return m_ZoomFactor; }

protected:
float m_ZoomFactor;//在构造函数中初始化1.00
BEGIN_MESSAGE_MAP(CJPEGTestDoc, CDocument)
ON_COMMAND(AFX_ID_PREVIEW_ZOOMOUT, OnViewZoomout)
ON_COMMAND(AFX_ID_PREVIEW_ZOOMIN, OnViewZoomin)
END_MESSAGE_MAP()
void CJPEGTestDoc::OnViewZoomout()
{
if (m_ZoomFactor<=0.0625) return;

if        (m_ZoomFactor == 2.00f) m_ZoomFactor = 1.50f;
else if (m_ZoomFactor == 1.50f) m_ZoomFactor = 1.00f;
else if (m_ZoomFactor == 1.00f)    m_ZoomFactor = 0.75f;
else if (m_ZoomFactor == 0.75f)    m_ZoomFactor = 0.50f;
else                            m_ZoomFactor/=2;

CStatusBar& statusBar = ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetStatusBar();
CString s;
s.Format(_T("%4.1f %%"),m_ZoomFactor*100);
statusBar.SetPaneText(2, s);

UpdateAllViews(NULL,WM_USER_NEWIMAGE);
}
void CJPEGTestDoc::OnViewZoomin()
{
if (m_ZoomFactor>=16) return;

if        (m_ZoomFactor == 0.50f) m_ZoomFactor = 0.75f;
else if (m_ZoomFactor == 0.75f) m_ZoomFactor = 1.00f;
else if (m_ZoomFactor == 1.00f)    m_ZoomFactor = 1.50f;
else if (m_ZoomFactor == 1.50f)    m_ZoomFactor = 2.00f;
else                            m_ZoomFactor*=2;

CStatusBar& statusBar = ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetStatusBar();
CString s;
s.Format(_T("%4.0f %%"),m_ZoomFactor*100);
statusBar.SetPaneText(2, s);

UpdateAllViews(NULL,WM_USER_NEWIMAGE);
}
6.显示的时候,做相应的更改
void CJPEGTestView::OnDraw(CDC* pDC)
{
CJPEGTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!m_Image.IsNull())
{
float zoom=pDoc->GetZoomFactor();
if (zoom==1)
m_Image.Draw(pDC->m_hDC,0,0);
else
{
pDC->SetStretchBltMode( HALFTONE ); //防止缩小图片失真
m_Image.Draw(pDC->GetSafeHdc(),CRect(0,0,(int)(m_Image.GetWidth()*zoom),(int)(m_Image.GetHeight()*zoom)));
  
}
}
差不多了。就这些,也是从网上看了相关的资料后,自己动手实验一下。

 

转载自:http://blog.sina.com.cn/s/blog_5f432e6a0100u993.html

这篇关于应用CImage类用文件和流的方式显示图片和放大缩小图片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/838876

相关文章

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

Vue3视频播放组件 vue3-video-play使用方式

《Vue3视频播放组件vue3-video-play使用方式》vue3-video-play是Vue3的视频播放组件,基于原生video标签开发,支持MP4和HLS流,提供全局/局部引入方式,可监听... 目录一、安装二、全局引入三、局部引入四、基本使用五、事件监听六、播放 HLS 流七、更多功能总结在 v

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常

k8s admin用户生成token方式

《k8sadmin用户生成token方式》用户使用Kubernetes1.28创建admin命名空间并部署,通过ClusterRoleBinding为jenkins用户授权集群级权限,生成并获取其t... 目录k8s admin用户生成token创建一个admin的命名空间查看k8s namespace 的

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二

Pandas处理缺失数据的方式汇总

《Pandas处理缺失数据的方式汇总》许多教程中的数据与现实世界中的数据有很大不同,现实世界中的数据很少是干净且同质的,本文我们将讨论处理缺失数据的一些常规注意事项,了解Pandas如何表示缺失数据,... 目录缺失数据约定的权衡Pandas 中的缺失数据None 作为哨兵值NaN:缺失的数值数据Panda

C#实现SHP文件读取与地图显示的完整教程

《C#实现SHP文件读取与地图显示的完整教程》在地理信息系统(GIS)开发中,SHP文件是一种常见的矢量数据格式,本文将详细介绍如何使用C#读取SHP文件并实现地图显示功能,包括坐标转换、图形渲染、平... 目录概述功能特点核心代码解析1. 文件读取与初始化2. 坐标转换3. 图形绘制4. 地图交互功能缩放