如何动态显示图片
2016-05-16 21:18
197 查看
有两种办法,第一种就是用PicTure控件。这种办法的优点是简单,缺点是当图片大小不一致的时候,图片显示会一大一小很难看。
第二种办法就是直接把位图图片画上去。优点是可以任意伸缩以后画上去,这样可以保证大小一致。很明显的缺点就是代码比较难,稍微不留意就会内存泄漏,程序崩溃。第二个缺点是分辨率会明显降低.
要注意的是,最好用工作线程来处理显示图片,否则主线程会堵塞,程序会崩溃.
一.用Picture控件动态显示图片
这个图片只支持bmp和ico.
步骤如下:
1.准备工作
把需要显示的图片都放到res资源文件夹中
2.添加资源
3.关联一个Picture控件变量
m_picture
4.在头文件中声明一个UINT型数组存放图片ID
如图:
5.在初始化对话框中把ID赋值给数组
如图:
6.创建一个线程
在头文件声明线程函数,如图:
在cpp文件中实现函数体,如图:
这里要传进来一个类指针,方便调用类的成员
设置一个定时器,定时显示图片。
7.在定时器函数中加载位图
7.在开始按钮中开始线程
就是那么简单,如果是显示表情的话这个就很实用了!
二.自己把图片画上去
前面1,2步骤一样
3.在头文件声明如下变量和函数
4.初始化数组和m_pOldBmp
5.创建线程
步骤和上面一样
6.定时器函数的实现
7.在OnPaint函数中画图片
在else语句中写如下代码
其中Stretch函数的实现为
FreeObject函数的实现为
8.在开始按钮中开启线程
AfxBeginThread(ShowThread, (LPVOID)this);
这样就可以随心所欲的显示指定大小的图片了。
温馨提醒:如果你的程序崩溃很可能是对象没释放,指针没删除,所以仔细一点!
第二种办法就是直接把位图图片画上去。优点是可以任意伸缩以后画上去,这样可以保证大小一致。很明显的缺点就是代码比较难,稍微不留意就会内存泄漏,程序崩溃。第二个缺点是分辨率会明显降低.
要注意的是,最好用工作线程来处理显示图片,否则主线程会堵塞,程序会崩溃.
一.用Picture控件动态显示图片
这个图片只支持bmp和ico.
步骤如下:
1.准备工作
把需要显示的图片都放到res资源文件夹中
2.添加资源
3.关联一个Picture控件变量
m_picture
4.在头文件中声明一个UINT型数组存放图片ID
如图:
5.在初始化对话框中把ID赋值给数组
如图:
6.创建一个线程
在头文件声明线程函数,如图:
在cpp文件中实现函数体,如图:
这里要传进来一个类指针,方便调用类的成员
设置一个定时器,定时显示图片。
7.在定时器函数中加载位图
static int i = 0; //用来控制图片的循环显示 void CMFCTESTDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (i > 20) i = 0; //循环显示 CBitmap bmp; bmp.LoadBitmap(m_uID[i++]);//加载图片 m_picture.SetBitmap(bmp); //把位图放到picture控件里显示 CDialogEx::OnTimer(nIDEvent); }
7.在开始按钮中开始线程
AfxBeginThread(ShowThread, (LPVOID)this);
就是那么简单,如果是显示表情的话这个就很实用了!
二.自己把图片画上去
前面1,2步骤一样
3.在头文件声明如下变量和函数
4.初始化数组和m_pOldBmp
5.创建线程
步骤和上面一样
6.定时器函数的实现
static int i = 0; //用来控制图片的循环显示 void CMFCTESTDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (i > 20) i = 0; //循环显示 FreeObject(); //释放前一个对象才能加载下一个对象,否则程序会崩溃 m_bmp.LoadBitmap(m_uID[i++]); //加载图片 CDC* pDC = GetDC(); //下面几行代码的作用是把位图"画"到自己的DC上去 m_dc.CreateCompatibleDC(pDC); ReleaseDC(pDC); m_pOldBmp = m_dc.SelectObject(&m_bmp); //把旧的对象留下来 Invalidate(FALSE); //使区域无效,通知重绘 CDialogEx::OnTimer(nIDEvent); }
7.在OnPaint函数中画图片
在else语句中写如下代码
if (m_dc.GetSafeHdc() == nullptr) //如果自己的dc上还没图片就不用画,否则会出错的 { CDialogEx::OnPaint(); } else { CPaintDC dc(this); ::FillRect(dc.GetSafeHdc(), &m_rect, (HBRUSH)GetStockObject(WHITE_BRUSH));//把背景刷为白色 BITMAP bm; m_bmp.GetBitmap(&bm); //得到位图的大小 LONG iWidth = bm.bmWidth; LONG iHeight = bm.bmHeight; Stretch(iWidth, iHeight, m_rect); //改变位图的大小 dc.StretchBlt(12, 15, iWidth, iHeight, &m_dc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); } CDialogEx::OnPaint();
其中Stretch函数的实现为
void CMFCTESTDlg::Stretch(LONG& iWidth, LONG& iHeight, RECT rect) { iWidth = rect.right - rect.left; iHeight = rect.bottom - rect.top; }
FreeObject函数的实现为
void CMFCTESTDlg::FreeObject() { if (m_dc.GetSafeHdc()) //如果dc存在 { m_dc.SelectObject(m_pOldBmp);//把旧的DC放回去 m_dc.DeleteDC(); //删除对象 m_bmp.DeleteObject(); } }
8.在开始按钮中开启线程
AfxBeginThread(ShowThread, (LPVOID)this);
这样就可以随心所欲的显示指定大小的图片了。
温馨提醒:如果你的程序崩溃很可能是对象没释放,指针没删除,所以仔细一点!
相关文章推荐
- 关于PreparedStatement操纵数据库
- [置顶] 【推荐】算法详解
- 前端---CSS中display-block & display-inline
- C++ 温习笔记(1) - main函数,类对象,作用域,防止头文件二次编译
- 整数解
- python的web问题
- python的web问题
- 记使用Android SQLite遇到的小问题
- http接口自动化测试框架实现
- ijkplayer阅读学习笔记之ijk源代码获取
- int main( int argc ,char** argv) windows下如何传递参数
- Android 连续点击实现一些隐蔽功能
- ButterKnife源码分析
- CentOS 7 安装好后,无法使用小键盘的解决办法
- unity中结合oculus制作VR场景控制相机的移动的三种方式
- postgresql数据库保存和下载二进制文件的几种方式
- jQuery中ajax的基本使用(2)
- 制作自己的Cydia发布源
- sqlite3命令语句, 文档小记
- Linux下more命令C语言实现实践