使用 StretchBlt 制作 缩略图标

31 篇文章 0 订阅
12 篇文章 0 订阅



//获取图片缩略图
//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;
      }
    }
  }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值