int GetEncoderClsid(const wchar_t* format, CLSID* pClsid)
{
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if (size == 0)
return -1;
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if (pImageCodecInfo == NULL)
return -1;
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;
}
}
free(pImageCodecInfo);
return -1;
}
BOOL SaveAs(CDC* pDC, const wchar_t* lpszFilename)
{
CBitmap* pBitmap = pDC->GetCurrentBitmap();
BITMAP bmp;
pBitmap->GetBitmap(&bmp);
CRect rcClient = CRect(0, 0, bmp.bmWidth, bmp.bmHeight);
CBitmap screenbitmap;
screenbitmap.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap *pOldBitmap = memDC.SelectObject(&screenbitmap);
memDC.SetStretchBltMode(HALFTONE);
memDC.StretchBlt(0, 0, rcClient.Width(), rcClient.Height(), pDC, 0, 0, rcClient.Width(), rcClient.Height(), SRCCOPY);
memDC.SelectObject(pOldBitmap);
Bitmap bitmap((HBITMAP)screenbitmap.GetSafeHandle(), NULL);
CLSID picClsid;
CString sFileName = lpszFilename;
CString sExt = sFileName.Right(3).MakeLower();
if (sExt == "jpg")
{
ULONG encoderQuality = 80; //压缩比例
EncoderParameters encoderParameters;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
encoderParameters.Parameter[0].Value = &encoderQuality;
GetEncoderClsid(L"image/jpeg", &picClsid);
bitmap.Save(lpszFilename, &picClsid, &encoderParameters);
}
else if (sExt == "png")
{
GetEncoderClsid(L"image/png", &picClsid);
bitmap.Save(lpszFilename, &picClsid, NULL);
}
else if (sExt == "bmp")
{
GetEncoderClsid(L"image/bmp", &picClsid);
bitmap.Save(lpszFilename, &picClsid, NULL);
}
else
{
DeleteObject(screenbitmap);
memDC.DeleteDC();
return FALSE;
}
DeleteObject(screenbitmap);
memDC.DeleteDC();
return TRUE;
}