如何动态显示图片

来源:互联网 发布:2017七天网络成绩查询 编辑:程序博客网 时间:2024/05/01 10:01

有两种办法,第一种就是用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);

这样就可以随心所欲的显示指定大小的图片了。
温馨提醒:如果你的程序崩溃很可能是对象没释放,指针没删除,所以仔细一点!

0 0