应用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

相关文章

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

SQL 中多表查询的常见连接方式详解

《SQL中多表查询的常见连接方式详解》本文介绍SQL中多表查询的常见连接方式,包括内连接(INNERJOIN)、左连接(LEFTJOIN)、右连接(RIGHTJOIN)、全外连接(FULLOUTER... 目录一、连接类型图表(ASCII 形式)二、前置代码(创建示例表)三、连接方式代码示例1. 内连接(I

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

JS 实现复制到剪贴板的几种方式小结

《JS实现复制到剪贴板的几种方式小结》本文主要介绍了JS实现复制到剪贴板的几种方式小结,包括ClipboardAPI和document.execCommand这两种方法,具有一定的参考价值,感兴趣的... 目录一、Clipboard API相关属性方法二、document.execCommand优点:缺点:

Python创建Excel的4种方式小结

《Python创建Excel的4种方式小结》这篇文章主要为大家详细介绍了Python中创建Excel的4种常见方式,文中的示例代码简洁易懂,具有一定的参考价值,感兴趣的小伙伴可以学习一下... 目录库的安装代码1——pandas代码2——openpyxl代码3——xlsxwriterwww.cppcns.c

Deepseek使用指南与提问优化策略方式

《Deepseek使用指南与提问优化策略方式》本文介绍了DeepSeek语义搜索引擎的核心功能、集成方法及优化提问策略,通过自然语言处理和机器学习提供精准搜索结果,适用于智能客服、知识库检索等领域... 目录序言1. DeepSeek 概述2. DeepSeek 的集成与使用2.1 DeepSeek API

CSS弹性布局常用设置方式

《CSS弹性布局常用设置方式》文章总结了CSS布局与样式的常用属性和技巧,包括视口单位、弹性盒子布局、浮动元素、背景和边框样式、文本和阴影效果、溢出隐藏、定位以及背景渐变等,通过这些技巧,可以实现复杂... 一、单位元素vm 1vm 为视口的1%vh 视口高的1%vmin 参照长边vmax 参照长边re