图像处理界面--缩略图的显示
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)
{
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 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
}
三、实现结果和小结
这个程序看似只是解决一个简单的问题,但是涉及到的东西很多。能够比较好的解决关键是找到了比较好的参考代码。同时也是因为我在很久之前就发现了这个问题,并且积极地去寻找解决方法。这两点应该都是最后得到比较好的结果必不可少的。
下一步就是需要把这样的程序进行整理整合,更好方便复用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!