一般的图像处理软件都对读入程序的图像文件建一个缩略图的列表,像ACDSee那样。笔者最近在做一个图像处理的项目,处理的原始数据就是图像文件。从项目一开始就想做一个缩略图,但一直苦于技术水平有限,且时间也不允许。最近两天闲暇之余就Google,百度了一下,仔细研究了一下缩略图的实现方法。其实用VC++实现一个缩略图的思想并不复杂。就是分两步:1.创建CListCtrl控件和CImageList图像列表,设置各自的相应属性。2.将你要显示的图像文件的缩略图做好,并制成位图文件加入到CImageList中,然后将每个图像文件设置成一个Item插入到CListCtrl中就完成了缩略的的制作。剩下的你就可以写各个消息的处理方法,以响应你对缩略图的操作。

说起来简单,但当笔者亲自实现时却遇到了许多的麻烦,最大的麻烦就是如何在内存里制作缩略图,如何将各个图像文件的缩略图制成Bitmap位图资源(因为CImageList只能加入位图资源)。笔者在内存中操作了半天,最后还是没成功。而且最大的问题是在内存中由于调色板的原因,在内存中画好的图像是黑白的。最后我想到了我们这个项目中应用的CXImage图像处理库了。我仔细的读了一下这个库的文档,正所谓“踏破铁鞋无觅处,得来全不费工夫”,我发现可以基于这个库提供的方法,很简单的实现缩略图。原理还是这个原理,只是应用CXImage后,原来的问题一一化解,原来的操作也更简单了。下面就把实现的过程及代码贴出来,以飨读者。

程序所达到的效果:

1.创建CListCtrl控件和CImageList图像列表,设置各自的相应属性。对于我的程序我是在图中左面的视图的OnCreate中动态创建的CListCtrl控件和CImageList图像列表的。

  1. int CWorkspaceBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
  2. {
  3. if (CBCGPDockingControlBar::OnCreate(lpCreateStruct) == -1)
  4. return -1;
  5. CRect rectDummy;
  6. rectDummy.SetRectEmpty ();
  7. // Create tree windows.
  8. //动态生产列表控件和图像列表
  9. m_ListCtl.Create(LVS_ICON|WS_CHILD | WS_VISIBLE|LVS_TYPEMASK,
  10. CRect(0,0,150,500),this,100);
  11. m_MyImageList.Create(64,64,ILC_COLOR24, 0, 1);
  12. return 0;
  13. }

2.设计一个左面视图的方法,使我们可以在文档类中调用这个方法为左面视图添加Items,这其中要完成的任务还有在内存中做好每个图像文件的Bitmap(位图资源)。

代码如下:

  1. void CWorkspaceBar::InitialListCtrl(int imageCount,CString *pImageNameList)
  2. //根据读入的文档数据初始化列表控件
  3. //传入参数imageCount是图像文件的总数,pImageNameList是各个图像文件按顺序的名字列表
  4. {
  5. //保存文档的数据
  6. m_imageCount=imageCount;
  7. m_pImageNameList=pImageNameList;
  8. //应用CXImage在内存中动态生产指定大小的位图
  9. CxImage image;        //声明CXImage对象
  10. for (int i=0;i<imageCount;i++)
  11. {
  12. //应用CXImage载入图像,本程序是相对路径
  13. image.Load(pImageNameList[i],CXIMAGE_FORMAT_BMP);
  14. //应用CXImage将图像变成我们指定的大小即96*96的,前面声明CImageList时就是96*96的
  15. image.Resample(96,96,2);
  16. //应用CXImage在内存中生产位图
  17. CDC *pDC = GetDC();
  18. HBITMAP hBit=image.MakeBitmap(pDC->GetSafeHdc());
  19. CBitmap bmp;
  20. bmp.Attach(hBit);
  21. //将位图加到图像列表中
  22. m_MyImageList.Add(&bmp,RGB(255, 255, 255));
  23. bmp.Detach();
  24. }
  25. //将图像列表与列表控件关联起来
  26. m_ListCtl.SetImageList(&m_MyImageList, LVSIL_NORMAL);
  27. //设置列表控件各项
  28. LVITEM item;
  29. item.mask=LVIF_TEXT|LVIF_IMAGE;
  30. item.iItem=0;   // 第1项
  31. item.iSubItem=0;        // 主项
  32. item.pszText="";
  33. item.iImage=0;  // 设置关联图像列表中指定图像的索引值
  34. m_ListCtl.InsertItem(&item);  // 添加第1项
  35. m_ListCtl.SetItemText(0,0,pImageNameList[0]);
  36. for (i=1;i<imageCount;i++)
  37. {
  38. item.iItem=i;           // 准备添加项
  39. item.iImage=i;
  40. m_ListCtl.InsertItem(&item);
  41. m_ListCtl.SetItemText(i,0,pImageNameList[i]);
  42. }
  43. DWORD  dwOldStyle,dwNewStyle;
  44. dwNewStyle = LVS_ICON;
  45. HWND  hWndLt=m_ListCtl.GetSafeHwnd();  // 获得列表视图控件的窗口句柄
  46. dwOldStyle=GetWindowLong(hWndLt, GWL_STYLE);  // 获得列表视图控件的窗口风格
  47. if((dwOldStyle & LVS_TYPEMASK)!=LVS_ICON)  // 判断当前的显示方式是不是所指定的方式
  48. {
  49. dwOldStyle &=~LVS_TYPEMASK;   // 从旧的窗口风格中屏蔽不必要的信息
  50. dwNewStyle |=dwOldStyle;   // 保持窗口其它风格不变,仅改变显示方式
  51. SetWindowLong(hWndLt, GWL_STYLE, dwNewStyle);  // 改变列表控件窗口风格
  52. }
  53. }

剩下的工作就是写各个消息的处理方法了,包括点击相应缩略图在对应的视图里显示各个图像等等。

       总结:本程序是基于CXImage影像处理库做的。CXImage是一个很好的图像处理库,在网上可以很容易下到,而且是开源的。笔者认为CXImage要优于GDI、GDI+。本程序在VC++6.0中调试通过,运行良好。

VC++基于CXImage库实现缩略图的更多相关文章

  1. VC基于单文档OpenGL框架

    本文是在VC6.0的环境下,运用MFC实现的OpenGL最基本框架,需要简单了解MFC编程(会在VC6.0里创建MFC单文档应用程序就行),甚至不必了解OpenGL的知识.以下是具体的步骤. 1.创建 ...

  2. vs2015部署---下一代VC运行时库系统:the Universal CRT

    前言 其实the Universal CRT(通用C运行时库)已经不能算是“下一代”,因为它已经在前两年伴随着Visual Studio 2015和Windows10发布.但是由于之前使用VS2015 ...

  3. WebGIS中基于控制点库进行SHP数据坐标转换的一种查询优化策略

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.前言 目前项目中基于控制点库进行SHP数据的坐标转换,流程大致为:遍 ...

  4. VC 运行时库 /MD、/MDd 和 /MT、/MTd

    这里总结下他们的区别,后面的那个'd'是代表DEBUG版本,没有'd'的就是RELEASE版本了. 首先说/MT /MT是 "multithread, static version ” 意思 ...

  5. 基于 libpcap库的sniffer程序

    基于 libpcap库的sniffer程序 Libpcap库是WireSharek和Tcpdump抓包程序的基础,利用libcap我们自己也可以实现自己的抓包程序,在网络上实时抓包分析,或者利用处理的 ...

  6. 基于Platinum库的DMS实现(android)

    接上篇博文:基于Platinum库的DMR实现(android) 文章讲述了如何使用Platinum库实现DMR 今天同样使用该库,来讲解一下DMS的实现 关于该库如何编译,请参考这篇博文:NDK下 ...

  7. vc 基于对话框多线程编程实例——线程之间的通信

     vc基于对话框多线程编程实例——线程之间的通信 实例:

  8. GD库 图片缩略图 图片水印

    /** * GD库 图片缩略图 *//*$image = imagecreatefromjpeg("1.jpg");var_dump($image);exit;$width = i ...

  9. 基于jsmpeg库下使用ffmpeg创建视频流连接websocket中继器传输视频并播放

    这个功能的基本工作是这样的: 1.使用node运行jsmpeg库下的websocket-relay.js文件,这个文件的作用是创建一个websocket视频传输中继器 2.运行ffmpeg,将输出发送 ...

随机推荐

  1. mysqli一些常用方法及详解

    mysqli一些常用方法及详解 1.die()函数:表示向用户输出引号中的内容后,程序终止运行,提示定制的出错信息 ex: $conn = mysqli_connect("localhost ...

  2. DB-MySQL:MySQL 索引

    ylbtech-DB-MySQL:MySQL 索引 1.返回顶部 1. MySQL 索引 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果 ...

  3. ffmpeg x264编译与使用介绍

    问题1:我用的是最新版本的ffmpeg和x264,刚刚编译出来,编译没有问题,但是在linux 环境使用ffmpeg的库时发现报错error C3861: 'UINT64_C': identifier ...

  4. GCD与dispatch_group总结

    GCD 可以看作是集合类的操作: 集合是queue,元素是block: 集合只能添加对象,删除对象由系统完成. 同理,NSOperationQueue也可以看作是一个集合管理器. dispatch_g ...

  5. Unity 导入的模型检测不到碰撞

    解决方案 添加Mesh Collider和rigidbody,并且Collider里边2个勾要勾上. 这是我碰到的问题.如果没解决你的问题,别打我,逃~

  6. python简单的购物系统

    #coding = utf-8 #2016-11-19#我的工资是存在文件中的,执行后会判断是否存过工资,如果存过无需输入,直接购物,没存过需要输入工资#wages.txt是存工资的文件 import ...

  7. ZBrush中Local模式的旋转

    刚接触ZBrush®的小伙伴可能对Local(局部)有了简单的了解,但是大多数人对它的认识还是比较模糊的,那么在本文中小编将对local命令做详细说明.此工具可以控制视图的旋转轴心点的位置,默认情况下 ...

  8. 省选模板_STL

    目录: 1. multiset 2. reverse 1.multiset namespace STL{ int main(){ multiset<int>::iterator s; mu ...

  9. SASS概览

    1.安装: sass需要使用ruby,首先安装ruby,之后: gem install sass 编译: sass input.scss output.css 2.快速入门: 变量: .scss 变量 ...

  10. BZOJ 4182 Shopping (点分治+树上多重背包)

    题目大意:给你一颗树,你有$m$元钱,每个节点都有一种物品,价值为$w$,代价为$c$,有$d$个,如果在$u$和$v$两个城市都购买了至少一个物品,那么$u,v$路径上每个节点也都必须买至少一个物品 ...