VC++基於CXImage庫實現縮略圖


一般的圖像處理軟件都對讀入程序的圖像文件建一個縮略圖的列表,像ACDSee那樣。筆者最近在做一個圖像處理的項目,處理的原始數據就是圖像文件。從項目一開始就想做一個縮略圖,但一直苦於技術水平有限,且時間也不允許。最近兩天閑暇之余就Google,百度了一下,仔細研究了一下縮略圖的實現方法。其實用VC++實現一個縮略圖的思想並不復雜。就是分兩步:1.創建CListCtrl控件和CImageList圖像列表,設置各自的相應屬性。2.將你要顯示的圖像文件的縮略圖做好,並制成位圖文件加入到CImageList中,然后將每個圖像文件設置成一個Item插入到CListCtrl中就完成了縮略的的制作。剩下的你就可以寫各個消息的處理方法,以響應你對縮略圖的操作。

       說起來簡單,但當筆者親自實現時卻遇到了許多的麻煩,最大的麻煩就是如何在內存里制作縮略圖,如何將各個圖像文件的縮略圖制成Bitmap位圖資源(因為CImageList只能加入位圖資源)。筆者在內存中操作了半天,最后還是沒成功。而且最大的問題是在內存中由於調色板的原因,在內存中畫好的圖像是黑白的。最后我想到了我們這個項目中應用的CXImage圖像處理庫了。我仔細的讀了一下這個庫的文檔,正所謂“踏破鐵鞋無覓處,得來全不費工夫”,我發現可以基於這個庫提供的方法,很簡單的實現縮略圖。原理還是這個原理,只是應用CXImage后,原來的問題一一化解,原來的操作也更簡單了。下面就把實現的過程及代碼貼出來,以饗讀者。

程序所達到的效果:

【引用】VC++基於CXImage庫實現縮略圖 - psunbird - psunbird的博客

1.創建CListCtrl控件和CImageList圖像列表,設置各自的相應屬性。對於我的程序我是在圖中左面的視圖的OnCreate中動態創建的CListCtrl控件和CImageList圖像列表的。

 

[cpp]  view plain  copy
 
  1. int CWorkspaceBar::OnCreate(LPCREATESTRUCT lpCreateStruct)   
  2. {  
  3.  if (CBCGPDockingControlBar::OnCreate(lpCreateStruct) == -1)  
  4.   return -1;  
  5.    
  6.  CRect rectDummy;  
  7.  rectDummy.SetRectEmpty ();  
  8.   
  9.  // Create tree windows.  
  10.  //動態生產列表控件和圖像列表  
  11.  m_ListCtl.Create(LVS_ICON|WS_CHILD | WS_VISIBLE|LVS_TYPEMASK,  
  12.                                  CRect(0,0,150,500),this,100);  
  13.  m_MyImageList.Create(64,64,ILC_COLOR24, 0, 1);  
  14.    
  15.  return 0;  
  16. }  

 

 

       2.設計一個左面視圖的方法,使我們可以在文檔類中調用這個方法為左面視圖添加Items,這其中要完成的任務還有在內存中做好每個圖像文件的Bitmap(位圖資源)。

 

代碼如下:

[cpp]  view plain  copy
 
  1. void CWorkspaceBar::InitialListCtrl(int imageCount,CString *pImageNameList)  
  2. //根據讀入的文檔數據初始化列表控件  
  3.   
  4. //傳入參數imageCount是圖像文件的總數,pImageNameList是各個圖像文件按順序的名字列表  
  5. {  
  6.  //保存文檔的數據  
  7.  m_imageCount=imageCount;  
  8.  m_pImageNameList=pImageNameList;  
  9.   
  10.  //應用CXImage在內存中動態生產指定大小的位圖  
  11.  CxImage image;        //聲明CXImage對象  
  12.  for (int i=0;i<imageCount;i++)  
  13.  {  
  14.   //應用CXImage載入圖像,本程序是相對路徑  
  15.   image.Load(pImageNameList[i],CXIMAGE_FORMAT_BMP);  
  16.    
  17.   //應用CXImage將圖像變成我們指定的大小即96*96的,前面聲明CImageList時就是96*96的  
  18.   image.Resample(96,96,2);  
  19.   //應用CXImage在內存中生產位圖  
  20.   CDC *pDC = GetDC();  
  21.   HBITMAP hBit=image.MakeBitmap(pDC->GetSafeHdc());  
  22.   CBitmap bmp;  
  23.   bmp.Attach(hBit);  
  24.   //將位圖加到圖像列表中  
  25.   m_MyImageList.Add(&bmp,RGB(255, 255, 255));  
  26.   bmp.Detach();  
  27.  }  
  28.  //將圖像列表與列表控件關聯起來  
  29.  m_ListCtl.SetImageList(&m_MyImageList, LVSIL_NORMAL);  
  30.  //設置列表控件各項  
  31.  LVITEM item;  
  32.   item.mask=LVIF_TEXT|LVIF_IMAGE;  
  33.  item.iItem=0;   // 第1項  
  34.   item.iSubItem=0;        // 主項  
  35.   item.pszText="";  
  36.   item.iImage=0;  // 設置關聯圖像列表中指定圖像的索引值  
  37.   m_ListCtl.InsertItem(&item);  // 添加第1項  
  38.  m_ListCtl.SetItemText(0,0,pImageNameList[0]);  
  39.    
  40.  for (i=1;i<imageCount;i++)  
  41.  {  
  42.   item.iItem=i;           // 准備添加項  
  43.    item.iImage=i;  
  44.    m_ListCtl.InsertItem(&item);  
  45.   m_ListCtl.SetItemText(i,0,pImageNameList[i]);  
  46.  }  
  47.  DWORD  dwOldStyle,dwNewStyle;   
  48.  dwNewStyle = LVS_ICON;  
  49.  HWND  hWndLt=m_ListCtl.GetSafeHwnd();  // 獲得列表視圖控件的窗口句柄  
  50.  dwOldStyle=GetWindowLong(hWndLt, GWL_STYLE);  // 獲得列表視圖控件的窗口風格  
  51.  if((dwOldStyle & LVS_TYPEMASK)!=LVS_ICON)  // 判斷當前的顯示方式是不是所指定的方式  
  52.  {  
  53.   dwOldStyle &=~LVS_TYPEMASK;   // 從舊的窗口風格中屏蔽不必要的信息  
  54.   dwNewStyle |=dwOldStyle;   // 保持窗口其它風格不變,僅改變顯示方式  
  55.   SetWindowLong(hWndLt, GWL_STYLE, dwNewStyle);  // 改變列表控件窗口風格  
  56.  }  
  57. }  

 

剩下的工作就是寫各個消息的處理方法了,包括點擊相應縮略圖在對應的視圖里顯示各個圖像等等。

       總結:本程序是基於CXImage影像處理庫做的。CXImage是一個很好的圖像處理庫,在網上可以很容易下到,而且是開源的。筆者認為CXImage要優於GDI、GDI+。本程序在VC++6.0中調試通過,運行良好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM