根据压缩率缩减图片

 HGLOBAL QualityJPG( //转换图像为JPG的数据格式并拥有不同的质量,返回值:非零 - 装有图像数据的堆句柄.零 - 失败
Image * pImage, //源图像
long lQuality, //质量(0 - 100)
LPDWORD pdwDataSize) //转换后的数据大小
{
BOOL bIsSucceeded = FALSE;
CONST UINT uBmpFileHeader =
sizeof(BITMAPFILEHEADER) +
sizeof(BITMAPINFOHEADER); 

//计算需要的内存,最小不得小于 1KB(因为在图像比较小的情况下JPG的尺寸可能超过BMP)
UINT uImageSize = pImage->GetWidth() * pImage->GetHeight() * 4 + uBmpHeader;
if(uImageSize < 0x400)uImageSize = 0x400;

HGLOBAL hGlobal = NULL;
IStream * pStream = NULL;
EncoderParameters * pEncoderParameters = NULL;
ULARGE_INTEGER uliDataSize;
do
{
//创建内存
hGlobal = GlobalAlloc(GMEM_FIXED,uImageSize);
if(!hGlobal)break;
//创建流指针
HRESULT hResult = CreateStreamOnHGlobal(hGlobal,FALSE,&pStream);
if(FAILED(hResult))break;
//只需要1个参数
pEncoderParameters = new EncoderParameters + sizeof(EncoderParameter) * 0;
pEncoderParameters->Count = 1;
pEncoderParameters->Parameter[0].Guid = EncoderQuality;
pEncoderParameters->Parameter[0].Type = EncoderParameterValueTypeLong;
pEncoderParameters->Parameter[0].NumberOfValues = 1;
pEncoderParameters->Parameter[0].Value = &lQuality;
//获得编码器的CLSID
CLSID EncoderClsid;
if(!GetImageEncoderClsid(L"image/jpeg",&EncoderClsid))break;
//编码
Status sResult = pImage->Save(pStream,&EncoderClsid,pEncoderParameters);
if(sResult != Ok)break;
//获取数据的大小
LARGE_INTEGER liSeek;
liSeek.QuadPart = 0i64;
pStream->Seek(liSeek,STREAM_SEEK_CUR,&uliDataSize);

bIsSucceeded = TRUE;
}while(false);

//释放资源
if(pEncoderParameters)delete pEncoderParameters;
if(pStream)pStream->Release();

if(bIsSucceeded)
{
if(pdwDataSize)*pdwDataSize = uliDataSize.LowPart;
return hGlobal;
}
else
{
if(hGlobal)GlobalFree(hGlobal);
return HGLOBAL(NULL);
}
}
以前写的软件里的模块函数
返回值是 HGLOBAL 你把 Save 那里改成存到硬盘上,就是你自己的函数了 
posted on 2012-02-21 09:41  小水人  阅读(195)  评论(0编辑  收藏  举报