使用GDI+保存位图文件为PNG文件

1.添加头文件

#include <ocidl.h>  
#include <olectl.h>
#include <stdio.h>
#include <atlconv.h>

#include <GdiPlus.h>
using namespace Gdiplus;

#pragma comment( lib , "gdiplus.lib" )

2.添加COM初始化及GDI+初始化

CoInitialize( NULL );
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR           gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

3.功能函数

int GetImageCLSID(const   WCHAR*   format,   CLSID*   pCLSID) 
{  
    //得到格式为format的图像文件的编码值,访问该格式图像的COM组件的GUID值保存在pCLSID中 
    UINT num  = 0; 
    UINT size = 0; 

    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL; 
    GetImageEncodersSize(&num,   &size); 

    if(size == 0) 
        return FALSE;   //   编码信息不可用 

    //分配内存 
    pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); 
    if(pImageCodecInfo == NULL) 
        return FALSE;   //   分配失败 

    //获得系统中可用的编码方式的所有信息 
    GetImageEncoders(num, size, pImageCodecInfo); 

    //在可用编码信息中查找format格式是否被支持 
    for(UINT i = 0; i < num; ++i) 
    {
        //MimeType:编码方式的具体描述 
        if(wcscmp(pImageCodecInfo[i].MimeType, format) == 0) 
        { 
            *pCLSID = pImageCodecInfo[i].Clsid; 
            free(pImageCodecInfo); 
            return TRUE; 
        } 
    } 

    free(pImageCodecInfo); 
    return FALSE; 
}

BOOL BmpToPNG( char* strBmpFile, char* strPngFile )
{
    FILE* cbfBmp = fopen( strBmpFile, "rb" );
    FILE* cbfImage = fopen( strPngFile, "wb" );

    fseek( cbfBmp, 0, SEEK_END );
    int iBmpSize = ftell( cbfBmp );
    fseek( cbfBmp, 0, SEEK_SET );
    HGLOBAL hMemBmp = GlobalAlloc(GMEM_FIXED, iBmpSize);
    if (hMemBmp == NULL) return FALSE;

    IStream* pStmBmp = NULL;
    CreateStreamOnHGlobal(hMemBmp, FALSE, &pStmBmp);
    if (pStmBmp == NULL)
    {
        GlobalFree(hMemBmp);

        fclose( cbfBmp );
        fclose( cbfImage );

        return FALSE;
    }
    BYTE* pbyBmp = (BYTE *)GlobalLock(hMemBmp);
    fread( pbyBmp, iBmpSize, 1, cbfBmp );

    Image* imImage = NULL;
    imImage = Image::FromStream(pStmBmp, FALSE);
    if (imImage == NULL)
    {
        GlobalUnlock(hMemBmp);
        GlobalFree(hMemBmp);

        fclose( cbfBmp );
        fclose( cbfImage );

        return FALSE;
    }
    USES_CONVERSION;
    CLSID clImageClsid;
    GetImageCLSID(A2W("image/png"), &clImageClsid);

    HGLOBAL hMemImage = GlobalAlloc(GMEM_MOVEABLE, 0);
    if (hMemImage == NULL)
    {
        pStmBmp->Release();
        GlobalUnlock(hMemBmp);
        GlobalFree(hMemBmp);
        if (imImage != NULL)
            delete imImage;

        fclose( cbfBmp );
        fclose( cbfImage );

        return FALSE;
    }
    IStream* pStmImage = NULL;
    CreateStreamOnHGlobal(hMemImage, TRUE, &pStmImage);
    if (pStmImage == NULL)
    {
        pStmBmp->Release();
        GlobalUnlock(hMemBmp);
        GlobalFree(hMemBmp);
        GlobalFree(hMemImage);
        if (imImage != NULL)
            delete imImage;

        fclose( cbfBmp );
        fclose( cbfImage );

        return FALSE;
    }   
    imImage->Save(pStmImage, &clImageClsid);
    if (pStmImage == NULL)
    {
        pStmBmp->Release();
        pStmImage->Release();
        GlobalUnlock(hMemBmp);
        GlobalFree(hMemBmp);
        GlobalFree(hMemImage);
        if (imImage != NULL)
            delete imImage;

        fclose( cbfBmp );
        fclose( cbfImage );

        return FALSE;
    }
    LARGE_INTEGER liBegin = {0};
    pStmImage->Seek(liBegin, STREAM_SEEK_SET, NULL);
    BYTE* pbyImage = (BYTE *)GlobalLock(hMemImage);
    fwrite( pbyImage, GlobalSize(hMemImage), 1, cbfImage );

    if (imImage != NULL) delete imImage;
    pStmBmp->Release();
    pStmImage->Release();
    GlobalUnlock(hMemBmp);
    GlobalUnlock(hMemImage);
    GlobalFree(hMemBmp);
    GlobalFree(hMemImage);

    fclose( cbfBmp );
    fclose( cbfImage );

    return TRUE;
}

4.COM反初始化及关闭GDI+

GdiplusShutdown(gdiplusToken);
CoUninitialize();

原文地址:https://www.cnblogs.com/LinuxHunter/p/2592015.html