读取文件数据后创建IStream对象,再调用IStream类方法read将JPG数据以二进制流读取出来。
使用GetImageEncodersSize之前一定要初始化GDIplus。最好在函数里面
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
退出的时候记得
Gdiplus::GdiplusShutdown(gdiplusToken);
1.添加GDI头文件
#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")
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);
}
}
调用:
HANDLE hFile = CreateFile(L"F:\\nn\\m_2.bmp", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE){
DWORD dwFilesize = GetFileSize(hFile, NULL);//获取文件大小
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFilesize);//分配文件内存
if (hGlobal){
BYTE *pvData = (BYTE*)GlobalLock(hGlobal);
DWORD dwRead = 0;
ReadFile(hFile, pvData, dwFilesize, &dwRead, NULL);//将文件数据读取到内存中
GlobalUnlock(hGlobal);
{
IStream *pBMPStream = NULL;
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pBMPStream);//将二进制流存到流对象
if (SUCCEEDED(hr)){
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(pBMPStream);//这里可以改成图片路径
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];//申请1M的空间
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。否则读取不出来数据
WriteJPGFile(pJPGData, dwRead);
delete[] pJPGData;
}
}
// Get the class identifier for the JPEG encoder.
if (pJPGStream){
pJPGStream->Release();
}
if (pBMPStream){
pBMPStream->Release();
}
if (pIStorage){
pIStorage->Release();
}
}
}
GlobalFree(hGlobal);
}
CloseHandle(hFile);
}
demo:
http://download.csdn.net/detail/sz76211822/9819193