使用GDI中的Image类的构造函数,直接从文件路径读取图像后,调用Image类的Save方法将BMP转换成jpg。
使用GetImageEncodersSize之前一定要初始化GDIplus。最好在函数里面
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
退出的时候记得
Gdiplus::GdiplusShutdown(gdiplusToken);
1.添加头文件
#include < Gdiplus.h>
#pragma comment(lib, "Gdiplus.lib")
using namespace Gdiplus;
#include <Objbase.h>
#include <Objidl.h>
#pragma comment(lib, "Ole32.lib")
#pragma comment(lib, "Uuid.lib")
2.定义公共函数
INT 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
}
void WriteJPGFile(BYTE *pData, DWORD dwLen)
{
HANDLE hFile = CreateFile(L"F:\\1.jpg", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE){
DWORD dwWrite = 0;
WriteFile(hFile, pData, dwLen, &dwWrite, NULL);
CloseHandle(hFile);
}
}
3.调用
CLSID codecClsid;
GetEncoderClsid(L"image/jpeg", &codecClsid);
int iQuality = 100;
EncoderParameters encoderParameters;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
encoderParameters.Parameter[0].Value = &iQuality;
Image pImage(L"F:\\nn\\m_2.bmp");//这里可以改成图片路径
IStorage* pIStorage = NULL;
IStream* pJPGStream = NULL;
HRESULT hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);
if (SUCCEEDED(hr)){
hr = pIStorage->CreateStream(L"StreamImage1", STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pJPGStream);
DWORD dwErr = GetLastError();
if (SUCCEEDED(hr)){
Status bStatus = pImage.Save(pJPGStream, &codecClsid);//将bmp转jpg后保存在内存中
//Status bStatus = pImage.Save(L"f:\\1.jpg", &codecClsid);//如果是保存为文件则把注释去掉
BYTE * pJPGData = new BYTE[1024 * 1024];
memset(pJPGData, 0, 1024 * 1024);
LARGE_INTEGER move;
move.QuadPart = 0;
pJPGStream->Seek(move, STREAM_SEEK_SET, NULL);//定位到流的起始位置
DWORD dwRead = 0;
hr = pJPGStream->Read(pJPGData, 1024 * 1024, &dwRead);//在read之前必须seek。否则读取不出来数据。jpg数据已经保存在pJPGData中
WriteJPGFile(pJPGData, dwRead);
delete[] pJPGData;
}
}
// Get the class identifier for the JPEG encoder.
if (pJPGStream){
pJPGStream->Release();
}
if (pIStorage){
pIStorage->Release();
}
demo: http://download.csdn.net/detail/sz76211822/9819193