天天看点

图像处理界面--缩略图的显示

http://pan.baidu.com/s/1i5JGBFB

编写一个图像处理类的程序,实现缩略图是非常自然的想发。基于mfc+opencv框架,实现以下代码

style child border none

一、填写界面 主要实现图片的添加、删除、显示

图像处理界面--缩略图的显示

左边是listctrl控件(alignment为top),右边是textbox控件(client edge 为true)。textbox控件主要用来占个位置,具体显示的时候要进行重载处理。

二、实现缩略图

1)最方便使用的缩略图函数是Gdiplus下的 GetThumbnailImage函数

        Bitmap* pThumbnail = static_cast<Bitmap*>(img.GetThumbnailImage(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, NULL, NULL));

能够将大图转换为小图。为了使用Gdiplus,首先需要引入和初始化

#include <gdiplus.h>

using namespace Gdiplus;

#pragma comment(lib, "gdiplus.lib")   

ULONG_PTR GdiplusToken;

GdiplusStartupInput gdiplusStartupInput; 

在initdialog中

GdiplusStartup(&GdiplusToken, &gdiplusStartupInput, NULL);

2)添加图片函数,主要是将文件目录名push到m_VectorImageNames结构中

void CGOthumbnailDlg::OnBnClickedButtonAddimg()

{

    CString szFilters= _T("*(*.*)|*.*|jpg(*.jpg)|*.jpg|bmp(*.bmp)|*.bmp||");

    CFileDialog dlgFile(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilters,NULL,0,TRUE); 

    CString FilePathName ;

    if(dlgFile.DoModal()==IDOK){

        FilePathName = dlgFile.GetPathName();

    }

    m_VectorImageNames.push_back(FilePathName);

    DrawThumbnails();

}

3)为了图片保存在imagelist中,并且使用listctrl控件进行显示,并且在初始化的时候进行定义

    m_ImageListThumb.Create(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, ILC_COLOR24, 0, 1);

    m_ListThumbnail.SetImageList(&m_ImageListThumb, LVSIL_NORMAL);

    m_nSelectedItem = 0;

具体绘图函数

void CGOthumbnailDlg::DrawThumbnails(void)

    CBitmap*    pImage = NULL;

    HBITMAP        hBmp = NULL;

    POINT        pt;

    CString        strPath;

    // no images

    if (m_VectorImageNames.empty())

        return;

    //不自动刷新

    m_ListThumbnail.SetRedraw(FALSE);

    // reset our image list

    for (int i = 0; i<m_ImageListThumb.GetImageCount(); i++)

        m_ImageListThumb.Remove(i);    

    // remove all items from list view

    if (m_ListThumbnail.GetItemCount() != 0)

        m_ListThumbnail.DeleteAllItems();

    // set the size of the image list

    m_ImageListThumb.SetImageCount(m_VectorImageNames.size());

    // draw the thumbnails

    for (int i = 0;i<m_VectorImageNames.size();i++)

    {        

        USES_CONVERSION;

        Bitmap img( m_VectorImageNames[i].AllocSysString());

        //使用GDI直接获得thumbnail

        Bitmap* pThumbnail = static_cast<Bitmap*>(img.GetThumbnailImage(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, NULL, NULL));

        // attach the thumbnail bitmap handle to an CBitmap object

        pThumbnail->GetHBITMAP(NULL, &hBmp);

        pImage = new CBitmap();         

        pImage->Attach(hBmp);

        m_ImageListThumb.Replace(i, pImage, NULL);

        m_ListThumbnail.InsertItem(i, m_VectorImageNames[i], i);

        delete pImage;

        delete pThumbnail;

    //显示thumbnail

    m_ListThumbnail.SetRedraw(); 

4)点击图片能够显示大图

void CGOthumbnailDlg::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)

    // retrieve message info.

    LPNMITEMACTIVATE pItemAct = (LPNMITEMACTIVATE)pNMHDR;

    // determine which item receives the click

    LVHITTESTINFO  hitTest;

    ZeroMemory(&hitTest, sizeof(LVHITTESTINFO));

    hitTest.pt = pItemAct->ptAction;

    m_ListThumbnail.SendMessage(LVM_SUBITEMHITTEST, 0, (LPARAM)&hitTest);

    // draw the selected image

    if ( hitTest.iItem >= 0)

    {

        m_nSelectedItem = hitTest.iItem;

        DrawSelectedImage();

    // select the item clicked

    *pResult = 0;    

void CGOthumbnailDlg::DrawSelectedImage(void)

    Rect        DesRect;

    RECT        clRect;

    USES_CONVERSION;

    Image img(m_VectorImageNames[m_nSelectedItem].AllocSysString() );

    // get destination rectangle

    m_imagerect.GetClientRect(&clRect);

    DesRect.X = clRect.left;

    DesRect.Y = clRect.top;

    DesRect.Width = clRect.right - clRect.left;

    DesRect.Height = clRect.bottom - clRect.top;

    // draw the image

    Graphics gc( m_imagerect.GetDC()->GetSafeHdc() );

    gc.DrawImage(&img, DesRect);

5)重载textbox的基类,改为imagearea类,主要是重载paint函数

void CImageArea::OnPaint() 

    CPaintDC dc(this); // device context for painting

    // TODO: Add your message handler code here

    CGOthumbnailDlg*  pWnd = static_cast<CGOthumbnailDlg*>(GetParent());

    if(pWnd->m_ListThumbnail.GetItemCount() != 0)

     pWnd->DrawSelectedImage();

    // Do not call CStatic::OnPaint() for painting messages

三、实现结果和小结

这个程序看似只是解决一个简单的问题,但是涉及到的东西很多。能够比较好的解决关键是找到了比较好的参考代码。同时也是因为我在很久之前就发现了这个问题,并且积极地去寻找解决方法。这两点应该都是最后得到比较好的结果必不可少的。

下一步就是需要把这样的程序进行整理整合,更好方便复用。

来自为知笔记(Wiz)

目前方向:图像拼接融合、图像识别

联系方式:[email protected]

继续阅读