使用 StretchBlt 制作 缩略图标
2016-08-19 17:35
302 查看
//获取图片缩略图
//hSrcBmp 源位图
//cx cy 目标大小(像素)
//bkColor 背景色
//hDstBmp 目标位图
BOOL GetImageThumb(HBITMAP hSrcBmp, int cx, int cy, COLORREF bkColor, HBITMAP *hDstBmp)
{
BOOL bRet = FALSE;
do
{
if(hSrcBmp == NULL || hDstBmp == NULL)
break;
//获取原始图片信息
BITMAP bitmap = {0};
if(GetObject(hSrcBmp, sizeof(bitmap), &bitmap) != sizeof(bitmap))
break;
//计算坐标 (锁定比例 & 居中显示)
int iSrcWidth = bitmap.bmWidth, iSrcHeight = bitmap.bmHeight;
double fZoom = min((double)cx/(double)iSrcWidth, (double)cy/(double)iSrcHeight);
int iDstWidth = (int)(iSrcWidth * fZoom);
int iDstHeight = (int)(iSrcHeight * fZoom);
int ixDst = (cx - iDstWidth)/2;
int iyDst = (cy - iDstHeight)/2;
//创建内存参考DC
HDC hRefDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
HBITMAP hRefBmp = CreateBitmap(64, 64, 1, 32, NULL);
HBITMAP hOldRefBmp = (HBITMAP)SelectObject(hRefDC, hRefBmp);
//源图内存DC & 选入源图
HDC hSrcDC = CreateCompatibleDC(hRefDC);
HBITMAP hOldSrcBmp = (HBITMAP)SelectObject(hSrcDC, hSrcBmp);
//目标内存DC & 选入目标位图
DeleteObject(*hDstBmp);
HDC hDstDC = CreateCompatibleDC(hRefDC);
*hDstBmp = CreateCompatibleBitmap(hRefDC, cx, cy);
HBITMAP hOldDstBmp = (HBITMAP)SelectObject(hDstDC, *hDstBmp);
SetStretchBltMode(hDstDC, HALFTONE); //缩放半色调
//填充背景色
HBRUSH hBursh = CreateSolidBrush(bkColor);
RECT rcFill = {0, 0, cx, cy};
FillRect(hDstDC, &rcFill, hBursh);
DeleteObject(hBursh); hBursh = NULL;
//贴图到内存DC
StretchBlt(hDstDC, //dst DC
ixDst, iyDst, iDstWidth, iDstHeight, //目标位置
hSrcDC,
0, 0, iSrcWidth, iSrcHeight, //源位置
SRCCOPY);
//结束清理
SelectObject(hDstDC, hOldDstBmp);
DeleteDC(hDstDC);
SelectObject(hSrcDC, hSrcBmp);
DeleteDC(hSrcDC);
SelectObject(hRefDC, hOldRefBmp);
DeleteObject(hRefBmp);
DeleteDC(hRefDC);
bRet = TRUE;
} while (0);
return bRet;
}
//测试用例, 使用CFileDialog 选择图像文件, 在C盘下生成 tThumb.bmp
#include <atlimage.h>
void CT2DDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(TRUE);
if(dlg.DoModal() == IDOK)
{
CImage srcImage, dstImage;
if(srcImage.Load(dlg.GetPathName()) == S_OK)
{
HBITMAP hDstBmp = NULL;
if(GetImageThumb((HBITMAP)srcImage, 64, 64, RGB(255,255,255), &hDstBmp))
{
dstImage.Attach(hDstBmp);
dstImage.Save(_T("C:\\tThumb.bmp"));
dstImage.Detach();
}
if(hDstBmp)
{
DeleteObject(hDstBmp); hDstBmp = NULL;
}
}
}
}
//hSrcBmp 源位图
//cx cy 目标大小(像素)
//bkColor 背景色
//hDstBmp 目标位图
BOOL GetImageThumb(HBITMAP hSrcBmp, int cx, int cy, COLORREF bkColor, HBITMAP *hDstBmp)
{
BOOL bRet = FALSE;
do
{
if(hSrcBmp == NULL || hDstBmp == NULL)
break;
//获取原始图片信息
BITMAP bitmap = {0};
if(GetObject(hSrcBmp, sizeof(bitmap), &bitmap) != sizeof(bitmap))
break;
//计算坐标 (锁定比例 & 居中显示)
int iSrcWidth = bitmap.bmWidth, iSrcHeight = bitmap.bmHeight;
double fZoom = min((double)cx/(double)iSrcWidth, (double)cy/(double)iSrcHeight);
int iDstWidth = (int)(iSrcWidth * fZoom);
int iDstHeight = (int)(iSrcHeight * fZoom);
int ixDst = (cx - iDstWidth)/2;
int iyDst = (cy - iDstHeight)/2;
//创建内存参考DC
HDC hRefDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
HBITMAP hRefBmp = CreateBitmap(64, 64, 1, 32, NULL);
HBITMAP hOldRefBmp = (HBITMAP)SelectObject(hRefDC, hRefBmp);
//源图内存DC & 选入源图
HDC hSrcDC = CreateCompatibleDC(hRefDC);
HBITMAP hOldSrcBmp = (HBITMAP)SelectObject(hSrcDC, hSrcBmp);
//目标内存DC & 选入目标位图
DeleteObject(*hDstBmp);
HDC hDstDC = CreateCompatibleDC(hRefDC);
*hDstBmp = CreateCompatibleBitmap(hRefDC, cx, cy);
HBITMAP hOldDstBmp = (HBITMAP)SelectObject(hDstDC, *hDstBmp);
SetStretchBltMode(hDstDC, HALFTONE); //缩放半色调
//填充背景色
HBRUSH hBursh = CreateSolidBrush(bkColor);
RECT rcFill = {0, 0, cx, cy};
FillRect(hDstDC, &rcFill, hBursh);
DeleteObject(hBursh); hBursh = NULL;
//贴图到内存DC
StretchBlt(hDstDC, //dst DC
ixDst, iyDst, iDstWidth, iDstHeight, //目标位置
hSrcDC,
0, 0, iSrcWidth, iSrcHeight, //源位置
SRCCOPY);
//结束清理
SelectObject(hDstDC, hOldDstBmp);
DeleteDC(hDstDC);
SelectObject(hSrcDC, hSrcBmp);
DeleteDC(hSrcDC);
SelectObject(hRefDC, hOldRefBmp);
DeleteObject(hRefBmp);
DeleteDC(hRefDC);
bRet = TRUE;
} while (0);
return bRet;
}
//测试用例, 使用CFileDialog 选择图像文件, 在C盘下生成 tThumb.bmp
#include <atlimage.h>
void CT2DDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(TRUE);
if(dlg.DoModal() == IDOK)
{
CImage srcImage, dstImage;
if(srcImage.Load(dlg.GetPathName()) == S_OK)
{
HBITMAP hDstBmp = NULL;
if(GetImageThumb((HBITMAP)srcImage, 64, 64, RGB(255,255,255), &hDstBmp))
{
dstImage.Attach(hDstBmp);
dstImage.Save(_T("C:\\tThumb.bmp"));
dstImage.Detach();
}
if(hDstBmp)
{
DeleteObject(hDstBmp); hDstBmp = NULL;
}
}
}
}
相关文章推荐
- 使用 Fireworks 制作图标[硬盘篇]和原作者的一个[源文件]
- VC使用位图和图标制作按钮
- CSS3制作精美的iphone电话图标,不使用图片
- Delphi FMX 开发APP使用TrueType字库做图标(自己使用图标制作字体)
- 在iOS应用中使用字体图标及制作字体库
- 使用 Fireworks 制作图标[显示器篇]
- 第一次制作和使用图标字体-IcoMoon
- CSS3制作精美的iphone电话图标,不使用图片
- CSS--使用伪选择器制作箭头图标
- d3.js使用svg制作图标
- Symbian中图标的制作与使用
- VC使用位图和图标制作按钮
- Symbian中图标的制作与使用
- 使用CSS3制作72个webapp图标
- 使用Metro Studio制作Metro样式图标
- Symbian中图标的制作与使用
- VC使用位图和图标制作按钮
- VC++2010 Ribbon 透明图标快速制作使用方法
- 字符图标如何制作,使用
- 图标字体制作 -- 将SVG制作成图标字体文件,通过引入使用