gid plus resize image file size

使用duilib时,发现如果png颜色深度为32, 缩小显示后,有锯齿.

想到的最简单方法是,将文件转成需要的小size(e.g. 120*120 png to 36*36), 然后再设置到DuiLib控件中去显示.

转换完再显示,锯齿没有了.

void CMainDlg::ImgFileResize(const WCHAR* pcFilePathName, int iImgWidth, int iImgHeight)
{
    Gdiplus::Bitmap*    pOrgBmp = NULL;
    Gdiplus::Bitmap*    pResizedBmp = NULL;
    Gdiplus::Image*     pDesPic = NULL;
    CLSID               encoderClsid ;

    if (NULL == pcFilePathName)
        return;

    pOrgBmp = new Gdiplus::Bitmap(pcFilePathName);
    _ASSERT_EXPR(pOrgBmp, L"pOrgBmp = new Gdiplus::Bitmap(pcFilePathName);");
    if (NULL == pOrgBmp)
        return;

    pResizedBmp = ResizeClone(pOrgBmp, iImgWidth, iImgHeight);
    SAFE_DELETE(pOrgBmp);

    GetEncoderClsid(_T("image/png"), &encoderClsid);  
    pResizedBmp->Save(pcFilePathName, &encoderClsid, NULL);
    SAFE_DELETE(pResizedBmp);
}

Gdiplus::Bitmap* CMainDlg::ResizeClone(Bitmap *bmp, INT width, INT height)
{
    UINT o_height = bmp->GetHeight();
    UINT o_width = bmp->GetWidth();
    INT n_width = width;
    INT n_height = height;
    double ratio = ((double)o_width) / ((double)o_height);
    if (o_width > o_height)
    {
        // Resize down by width
        n_height = static_cast<UINT>(((double)n_width) / ratio);
    }
    else 
    {
        n_width = static_cast<UINT>(n_height * ratio);
    }
    Gdiplus::Bitmap* newBitmap = new Gdiplus::Bitmap(n_width, n_height, bmp->GetPixelFormat());
    Gdiplus::Graphics graphics(newBitmap);
    graphics.DrawImage(bmp, 0, 0, n_width, n_height);
    return newBitmap;
}

int CMainDlg::GetEncoderClsid(const   WCHAR*   format,   CLSID*   pClsid) 
{ 
    UINT     num   =   0;                     //   number   of   image   encoders 
    UINT     size   =   0;                   //   size   of   the   image   encoder   array   in   bytes 

    ImageCodecInfo*   pImageCodecInfo   =   NULL; 

    GetImageEncodersSize(&num,   &size); 
    if(size   ==   0) 
        return   -1;     //   Failure 

    pImageCodecInfo   =   (ImageCodecInfo*)(malloc(size)); 
    if(pImageCodecInfo   ==   NULL) 
        return   -1;     //   Failure 

    GetImageEncoders(num,   size,   pImageCodecInfo); 

    for(UINT   j   =   0;   j   <   num;   ++j) 
    { 
        if(   wcscmp(pImageCodecInfo[j].MimeType,   format)   ==   0   ) 
        { 
            *pClsid   =   pImageCodecInfo[j].Clsid; 
            free(pImageCodecInfo); 
            return   j;     //   Success 
        }         
    } 

    free(pImageCodecInfo); 
    return   -1;     //   Failure 
} 

在Duilib中看到了gdi+的初始化代码, 说明gdi和gdi+是可以混用的.

DuiLib底层绘图函数是用gdi做的

void CRenderEngine::DrawImage(
    HDC hDC, 
    HBITMAP hBitmap, 
    const RECT& rc, 
    const RECT& rcPaint,
    const RECT& rcBmpPart, 
    const RECT& rcCorners, 
    bool alphaChannel,
    BYTE uFade, 
    bool hole, 
    bool xtiled, 
    bool ytiled)
{
    ASSERT(::GetObjectType(hDC)==OBJ_DC || ::GetObjectType(hDC)==OBJ_MEMDC);

    /// @todo ls gdi 缩放绘图, 反锯齿处理加在这
    typedef BOOL (WINAPI *LPALPHABLEND)(HDC, int, int, int, int,HDC, int, int, int, int, BLENDFUNCTION);

如果要改DuiLib的底层还是比较蛋疼的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值