使用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的底层还是比较蛋疼的.