我用GDI+缩小一个JPG图片,从网上down下来的这个图片原本是208×275,大小为10K,我使用GDI+将尺寸缩小至151×200后,图片的大小反而变成了22K,我的代码如下:void compressImpl(const std::string& path, int size, UInt8 quality)
{
HBITMAP hbmReturn = NULL;
Bitmap* bmPhoto = NULL; std::wstring upath;
UnicodeConverter::toUTF16(path, upath); {
Bitmap image(upath.c_str()); int srcWidth = image.GetWidth();
int srcHeight = image.GetHeight(); float percent = 0;
int destX = 0, destY = 0;
if (srcWidth > srcHeight)
{
percent = ((float)size/(float)srcWidth);
destX = (int)((size - (srcWidth * percent))/2);
}
else
{
percent = ((float)size/(float)srcHeight);
destY = (int)((size - (srcHeight * percent))/2);
}
if (percent >= 1.0f)
return; // skip compress int destWidth = (int)(srcWidth * percent);
int destHeight = (int)(srcHeight * percent); bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat24bppRGB);
bmPhoto->SetResolution(image.GetHorizontalResolution(), image.GetVerticalResolution()); Graphics *grPhoto = Graphics::FromImage(bmPhoto);
Color colorW(255, 255, 255, 255);
grPhoto->Clear(colorW);
grPhoto->SetInterpolationMode(InterpolationModeHighQualityBicubic);
grPhoto->DrawImage(&image, Rect(destX, destY, destWidth, destHeight)); bmPhoto->GetHBITMAP(colorW, &hbmReturn);
delete grPhoto;
} // find appropriate encoder, jpeg
CLSID encoderClsid;
getEncoderClsid(L"image/jpeg", &encoderClsid); // set output quality for jpeg alone
EncoderParameters encoderParameters;
setEncoderQuality(&encoderParameters, quality); // output to image file with desired quality
bmPhoto->Save(upath.c_str(), &encoderClsid, &encoderParameters); // release resources
delete bmPhoto;
DeleteObject(hbmReturn);
}int getEncoderClsid(const WCHAR* format, void* clsid)
{
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)
{
*(CLSID*)clsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; //Success
}
} free(pImageCodecInfo);
return -1; // Failure
}void setEncoderQuality(void* params, UInt8 quality)
{
EncoderParameters* encoderParams = (EncoderParameters*)params;
encoderParams->Count = 1;
encoderParams->Parameter[0].Guid = EncoderQuality;
encoderParams->Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParams->Parameter[0].NumberOfValues = 1; encoderParams->Parameter[0].Value = &quality;
}
{
HBITMAP hbmReturn = NULL;
Bitmap* bmPhoto = NULL; std::wstring upath;
UnicodeConverter::toUTF16(path, upath); {
Bitmap image(upath.c_str()); int srcWidth = image.GetWidth();
int srcHeight = image.GetHeight(); float percent = 0;
int destX = 0, destY = 0;
if (srcWidth > srcHeight)
{
percent = ((float)size/(float)srcWidth);
destX = (int)((size - (srcWidth * percent))/2);
}
else
{
percent = ((float)size/(float)srcHeight);
destY = (int)((size - (srcHeight * percent))/2);
}
if (percent >= 1.0f)
return; // skip compress int destWidth = (int)(srcWidth * percent);
int destHeight = (int)(srcHeight * percent); bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat24bppRGB);
bmPhoto->SetResolution(image.GetHorizontalResolution(), image.GetVerticalResolution()); Graphics *grPhoto = Graphics::FromImage(bmPhoto);
Color colorW(255, 255, 255, 255);
grPhoto->Clear(colorW);
grPhoto->SetInterpolationMode(InterpolationModeHighQualityBicubic);
grPhoto->DrawImage(&image, Rect(destX, destY, destWidth, destHeight)); bmPhoto->GetHBITMAP(colorW, &hbmReturn);
delete grPhoto;
} // find appropriate encoder, jpeg
CLSID encoderClsid;
getEncoderClsid(L"image/jpeg", &encoderClsid); // set output quality for jpeg alone
EncoderParameters encoderParameters;
setEncoderQuality(&encoderParameters, quality); // output to image file with desired quality
bmPhoto->Save(upath.c_str(), &encoderClsid, &encoderParameters); // release resources
delete bmPhoto;
DeleteObject(hbmReturn);
}int getEncoderClsid(const WCHAR* format, void* clsid)
{
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)
{
*(CLSID*)clsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; //Success
}
} free(pImageCodecInfo);
return -1; // Failure
}void setEncoderQuality(void* params, UInt8 quality)
{
EncoderParameters* encoderParams = (EncoderParameters*)params;
encoderParams->Count = 1;
encoderParams->Parameter[0].Guid = EncoderQuality;
encoderParams->Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParams->Parameter[0].NumberOfValues = 1; encoderParams->Parameter[0].Value = &quality;
}
解决方案 »
- createthread后以前建立的socket失效了 请大家帮忙
- 重绘控件那种方法好。有没有相关资料。网上搜的好乱
- 请教如何隐藏MDI程序中的某个视图?
- 80分 求集成式即时通讯软件开发方面资料
- _variant_t 类型问题
- 求教:WSASendTo函数一次性 能传输多大的数据?
- 我想用VC给一个大型网站做个邮件服务器,请给建议
- 奇怪的问题,大家进来看看。。。。
- 学vc看什么书好?
- 请问这两句各是什么意思:(1)typedef DWORD WINAPI SH_FORMATDRIVE( HWND hwnd, UINT drive,UINT fmtID,UINT options);
- vc tab控件的使用
- 在设计开发一套数据中心的网络系统,求实现策略?
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
int A2U(const char* szA,wchar_t* szU,size_t cnt)
{
return MultiByteToWideChar (CP_ACP, 0, szA, -1, szU, cnt) ;
}
bool SaveImageToFile(Bitmap* pimage, LPCTSTR szFileName, ULONG quality)
//quality表示压缩等级,取值范围0-100,越小,压缩等级越大,图像质量越差
{
if(NULL==pimage || NULL==szFileName)
return false;
CLSID encoderClsid;
EncoderParameters encoderParameters,*pencoderParameters=NULL;
TCHAR* pstr;
TCHAR szFtr[16];
TCHAR strcode[32]=TEXT("image/");
pstr=_tcsrchr(szFileName,TEXT('.'));
if(NULL==pstr)
return false;
_tcscpy(szFtr,pstr+1);
_tcslwr(szFtr);
if(_tcscmp(TEXT("jpeg"),szFtr)==0 || _tcscmp(TEXT("jpg"),szFtr)==0)
{
_tcscat(strcode,TEXT("jpeg"));
pencoderParameters=&encoderParameters;
}
else
_tcscat(strcode,szFtr);
if(-1==GetEncoderClsid(strcode, &encoderClsid))
return false;
if(quality>100)
quality=100;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
encoderParameters.Parameter[0].Value = &quality;
#ifndef UNICODE
wchar_t wszFileName[MAX_PATH];
A2U(szFileName,wszFileName,MAX_PATH);
return Ok==pimage->Save(wszFileName, &encoderClsid, pencoderParameters)?true:false;
#else
return Ok==pimage->Save(szFileName, &encoderClsid, pencoderParameters)?true:false;
#endif
}
int GetEncoderClsid(LPCTSTR szFormat, CLSID* pClsid) // help
{
UINT j;
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);
#ifndef UNICODE
wchar_t wszFormat[32];
A2U(szFormat,wszFormat,32);
for(j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, wszFormat) == 0 )
#else
for(j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, szFormat) == 0 )
#endif
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}