Fork me on GitHub

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

http://pan.baidu.com/s/1i5JGBFB
编写一个图像处理类的程序,实现缩略图是非常自然的想发。基于mfc+opencv框架,实现以下代码
style child border none

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

左边是listctrl控件(alignment为top),右边是textbox控件(client edge 为true)。textbox控件主要用来占个位置,具体显示的时候要进行重载处理。
二、实现缩略图
1)最方便使用的缩略图函数是Gdiplus下的 GetThumbnailImage函数
        BitmappThumbnail = static_cast<Bitmap*>(img.GetThumbnailImage(THUMBNAIL_WIDTHTHUMBNAIL_HEIGHTNULLNULL));
能够将大图转换为小图。为了使用Gdiplus,首先需要引入和初始化
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment(lib"gdiplus.lib")   
ULONG_PTR GdiplusToken;
GdiplusStartupInput gdiplusStartupInput
在initdialog中
GdiplusStartup(&GdiplusToken, &gdiplusStartupInputNULL);
 
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_WIDTHTHUMBNAIL_HEIGHTILC_COLOR24, 0, 1);
    m_ListThumbnail.SetImageList(&m_ImageListThumbLVSIL_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 imgm_VectorImageNames[i].AllocSysString());
        //使用GDI直接获得thumbnail
        BitmappThumbnail = static_cast<Bitmap*>(img.GetThumbnailImage(THUMBNAIL_WIDTHTHUMBNAIL_HEIGHTNULLNULL));
        // attach the thumbnail bitmap handle to an CBitmap object
        pThumbnail->GetHBITMAP(NULL, &hBmp);
        pImage = new CBitmap();         
        pImage->Attach(hBmp);
        m_ImageListThumb.Replace(ipImageNULL);
        m_ListThumbnail.InsertItem(im_VectorImageNames[i], i);
        delete pImage;
        delete pThumbnail;
    }
    //显示thumbnail
    m_ListThumbnail.SetRedraw(); 
}
4)点击图片能够显示大图
void CGOthumbnailDlg::OnNMClickList1(NMHDR *pNMHDRLRESULT *pResult)
{
    // retrieve message info.
    LPNMITEMACTIVATE pItemAct = (LPNMITEMACTIVATE)pNMHDR;
 
    // determine which item receives the click
    LVHITTESTINFO  hitTest;
    ZeroMemory(&hitTestsizeof(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)
{
    CString        strPath;
    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 gcm_imagerect.GetDC()->GetSafeHdc() );
    gc.DrawImage(&imgDesRect);
}
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
}
三、实现结果和小结
这个程序看似只是解决一个简单的问题,但是涉及到的东西很多。能够比较好的解决关键是找到了比较好的参考代码。同时也是因为我在很久之前就发现了这个问题,并且积极地去寻找解决方法。这两点应该都是最后得到比较好的结果必不可少的。
下一步就是需要把这样的程序进行整理整合,更好方便复用。
 
 

 





目前方向:图像处理,人工智能
posted @ 2016-05-14 20:59  jsxyhelu  阅读(987)  评论(0编辑  收藏  举报