用VC开发缩略图功能

原贴地址: http://www.codeproject.com/listctrl/ThumbsViewer.asp#xx1195695xx

Thumbnails Viewer using ListCtrl

Sample Image - ThumbViewer.jpg

Introduction

There are several image libraries and sources currently available. So I made my mind up to make a free Image Viewer using a free image library, and I got many free demo programs. I think a good image viewer must be able to show thumbnail images in a selected directory. I found some sources showing thumbnails, but they didn't support several formats, only BMP files. This thumbnail viewer is based on CxImage, so if there is an image format supported by CxImage, this viewer also supports that format.

Implementation

I want to show you the core part in this article. How to make a CListCtrl, CImageList, and then how to load images and attach that image to an ImageList.

1. Creating CListCtrl and CImageList

I used a CListView instead of CListCtrl, but you know that CListView uses CListCtrl internally. So overriding Create(...) will make your icon view CListCtrl initially. And then on OnInitialUpdate(), make ImageList which can support 24 bit color images and attach to CListCtrl.

return CListView::Create(lpszClassName, _T("ListView"),
  dwStyle|LVS_SHOWSELALWAYS|LVS_ALIGNTOP|LVS_ICON|LVS_SINGLESEL|
  LVS_AUTOARRANGE, rect, pParentWnd, nID, pContext);

....
m_ImageListThumb.Create(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, ILC_COLOR24, 0, 1);
 ListCtrl.SetImageList(&m_ImageListThumb, LVSIL_NORMAL);

2. Load Images and Insert Items

Create a Compatible DC and a Bitmap Handle. Stretch a loaded image to the Bitmap Handle and then attach it to CBitmap. Finally, replace CBitmap with an image in the ImageList.

unsigned __stdcall CThumbViewerView::LoadThumbNail(LPVOID lpParam)
{
 CThumbViewerView* pView=(CThumbViewerView*)lpParam;
 CThumbViewerDoc* pDoc=pView->GetDocument();

 CListCtrl& ListCtrl=pView->GetListCtrl();
 CImageList* pImgList=&pView->m_ImageListThumb;

 // reset our image list
 for(int i=0; i<pImgList->GetImageCount(); i++)
  pImgList->Remove(i); 

 // remove all items from list view
 ListCtrl.DeleteAllItems();

 pImgList->SetImageCount(pDoc->m_vFileName.size());

 char path[MAX_PATH];
 vector<CString>::iterator iter;
 
 // Set redraw to FALSE to avoid flickering during adding new items
 ListCtrl.SetRedraw(FALSE);
 int nIndex=0;
 for(iter=pDoc->m_vFileName.begin(); 
     iter!=pDoc->m_vFileName.end() && pView->m_bTerminate!=true; 
     iter++, nIndex++)
 {
          ListCtrl.InsertItem(nIndex, *iter, nIndex);
 }

 ListCtrl.SetRedraw(TRUE);
 ListCtrl.Invalidate();

 // Create Brushes for Border and BackGround
 HBRUSH hBrushBorder=::CreateSolidBrush(RGB(192, 192, 192));
 HBRUSH hBrushBk=::CreateSolidBrush(RGB(255, 255, 255));

 // Border Size
 RECT rcBorder;
 rcBorder.left=rcBorder.top=0;
 rcBorder.right=THUMBNAIL_WIDTH;
 rcBorder.bottom=THUMBNAIL_HEIGHT;

 const float fRatio=(float)THUMBNAIL_HEIGHT/THUMBNAIL_WIDTH;

 int XDest, YDest, nDestWidth, nDestHeight;
 nIndex=0;
 for(iter=pDoc->m_vFileName.begin(); 
     iter!=pDoc->m_vFileName.end() && pView->m_bTerminate!=true; 
     iter++, nIndex++)
 {
  // Load Image File
  sprintf(path, "%s//%s", pDoc->m_strCurrentDirectory, *iter);

  int nImageType=pDoc->GetTypeFromFileName(path);
  if(nImageType==CXIMAGE_FORMAT_UNKNOWN)
   continue;

  CxImage image(path, nImageType);

  if(image.IsValid()==false)
   continue;

  // Calculate Rect to fit to canvas
  const float fImgRatio=(float)image.GetHeight()/image.GetWidth();
  if(fImgRatio > fRatio)
  {
   nDestWidth=THUMBNAIL_HEIGHT/fImgRatio;
   XDest=(THUMBNAIL_WIDTH-nDestWidth)/2;
   YDest=0;
   nDestHeight=THUMBNAIL_HEIGHT;
  }
  else
  {
   XDest=0;
   nDestWidth=THUMBNAIL_WIDTH;
   nDestHeight=THUMBNAIL_WIDTH*fImgRatio;
   YDest=(THUMBNAIL_HEIGHT-nDestHeight)/2;
  }

  CClientDC cdc(pView);
  HDC hDC=::CreateCompatibleDC(cdc.m_hDC);
  HBITMAP bm = CreateCompatibleBitmap(cdc.m_hDC, THUMBNAIL_WIDTH, 
                                      THUMBNAIL_HEIGHT);
  HBITMAP pOldBitmapImage = (HBITMAP)SelectObject(hDC,bm);
  // Draw Background
  ::FillRect(hDC, &rcBorder, hBrushBk);

  // Draw Image
  image.Stretch(hDC, XDest, YDest, nDestWidth, nDestHeight);

  // Draw Border
  ::FrameRect(hDC, &rcBorder, hBrushBorder);

  SelectObject(hDC, pOldBitmapImage);

  // Attach to Bitmap and Replace image in CImageList
  CBitmap bitmap;
  bitmap.Attach(bm);
  pImgList->Replace(nIndex, &bitmap, NULL);

  // Redraw only a current item for removing flickering and fast speed.
  ListCtrl.RedrawItems(nIndex, nIndex);

  // Release used DC and Object
  DeleteDC(hDC);
  DeleteObject(bm);
 }
 DeleteObject(hBrushBorder);
 DeleteObject(hBrushBk);

 ListCtrl.Invalidate();
 pView->m_bRunning=false;
 pView->m_bTerminate=false;

 _endthreadex( 0 );

 return 0;
}

Acknowledgment

You can download CxImage freely from here.

History

  • Ver. 1.0  15, Sep. 2003
    • First release.
  • Ver. 1.1  24, Mar. 2005
    • Fixed crashing when changing a directory fast.
    • Supports Unicode option using preprocessor _UNICODE.

About moah


Youngjin Kim lives in South Korea. I'm interested in every part of Computer Science, cause it has not been long time since graduate a University.
But now I'm working and researching on Pattern Recognition. Using that trying to recognize a Handwriting Prints. Korean and Chinese are my interesting Research Part.

Click here to view moah's online profile.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值