C++ BMP转JPG方法一

    xiaoxiao2021-04-12  37

    读取文件数据后创建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")

    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); } } 调用:

    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

    转载请注明原文地址: https://ju.6miu.com/read-667507.html

    最新回复(0)