您的位置:首页 > 其它

如何动态显示图片

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.在定时器函数中加载位图

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);

这样就可以随心所欲的显示指定大小的图片了。

温馨提醒:如果你的程序崩溃很可能是对象没释放,指针没删除,所以仔细一点!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: