C++ jpg内存中绘制图片,字体并以char*的形式输出

1.Gdi的调用

链接附加依赖项:gdiplus.lib

#include <comdef.h>//(不加这个可能会报错)
#include <GdiPlus.h>

//开始调用

ULONG_PTR                        g_pGdiToken = NULL;
Gdiplus::GdiplusStartupInput    g_gdiplusStartupInput;

Gdiplus::GdiplusStartup(&g_pGdiToken, &g_gdiplusStartupInput, NULL);

//结束调用

Gdiplus::GdiplusShutdown(g_pGdiToken);

2.Jpg转Gdi bitmap

在开始之前事先申请内存(临时new的时候不行,不知道为啥)

m_hImageMemPic = GlobalAlloc(GMEM_FIXED, MAXPICBUF);

// Jpg转换为Image;
bool JPG2Image(void *szBuf, DWORD dwBufSize)
{
    HGLOBAL hMem = m_hImageMemPic;
    Gdiplus::Image** ppImage = &m_pImagePic;
    
    m_sizePicOut.cx = 0;
    m_sizePicOut.cy = 0;

    int nMaxLen = MAXPICBUF;
    BOOL bAlloc = FALSE;
    if (hMem == NULL)
    {
        bAlloc = TRUE;
        hMem = GlobalAlloc(GMEM_FIXED, nMaxLen);
    }

    if (*ppImage != NULL)
    {
        delete *ppImage;
        *ppImage = NULL;
    }

    if (dwBufSize != 0)
    {
        IStream* pStmBmp = NULL;
        CreateStreamOnHGlobal(hMem, FALSE, &pStmBmp);
        BYTE* pbyBmp = (BYTE *)GlobalLock(hMem);
        memset(pbyBmp, 0, nMaxLen);
        memcpy(pbyBmp, szBuf, dwBufSize);
        ::GlobalUnlock(hMem);
        *ppImage = Gdiplus::Image::FromStream(pStmBmp, FALSE);
        if ((*ppImage) != NULL)
        {
            m_sizePicOut.cx = (*ppImage)->GetWidth();
            m_sizePicOut.cy = (*ppImage)->GetHeight();
        }
    }

    if (bAlloc)
    {
        GlobalFree(hMem);
    }

    return ((*ppImage) != NULL);

    /*CLSID pngClsid;
    GetEncoderClsid(L"image/bmp", &pngClsid);
    m_pImagePic->Save(L"Mosaic245.bmp", &pngClsid, NULL);*/
}

3.Gdi绘制图片

   HDC hdc = GetDC(NULL);
    HDC hTempMemDC = ::CreateCompatibleDC(NULL);
    HBITMAP bmpTmpDraw = ::CreateCompatibleBitmap(hdc, m_sizePicOut.cx, m_sizePicOut.cy);//hdc
    if (bmpTmpDraw == NULL) bmpTmpDraw = ::CreateCompatibleBitmap(hdc, m_sizePicOut.cx, m_sizePicOut.cy);
    if (bmpTmpDraw == NULL)
    {
        return;
    }
    HGDIOBJ oldObj = ::SelectObject(hTempMemDC, bmpTmpDraw);
    RECT rc;
    rc.left = 0;
    rc.top = 0;
    rc.right = m_sizePicOut.cx;
    rc.bottom = m_sizePicOut.cy;

 if (pImage)
    {
        Gdiplus::Graphics g(hdc);
        Gdiplus::ImageAttributes ImgAtt;
        ImgAtt.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
        g.DrawImage(pImage, Gdiplus::Rect(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top),
            0, 0, pImage->GetWidth(), pImage->GetHeight(),
            Gdiplus::UnitPixel, &ImgAtt, NULL, NULL);
    }

4.  绘制字体

 LOGFONTW lfont;
    memset(&lfont, 0, sizeof(lfont));
    int emSize = 70;
    lfont.lfHeight = -emSize; //   nHeight   注意使用负值,表示character height,  正值表示 cell height
    lfont.lfWeight = 400;//100;//FW_NORMAL,  //nWeight
    lfont.lfCharSet = GB2312_CHARSET;//;//ANSI_CHARSET
    wcscpy(lfont.lfFaceName, (L"微软雅黑"));  //   lpszFacename
    Gdiplus::Font gdifont(hdc, &lfont);
    
    Gdiplus::StringFormat strformat;
    strformat.SetAlignment(Gdiplus::StringAlignmentNear);//水平居左  
    strformat.SetLineAlignment(Gdiplus::StringAlignmentCenter);//垂直居中 
    Gdiplus::Font gFont(hdc, &lfont);
    Gdiplus::Color clr1(255, 255, 255);
    Gdiplus::SolidBrush    br1(clr1);
    Gdiplus::Graphics gdiGraphics(hdc);
    wchar_t tempText[256] = { 0 };
    int nLen = 0;
    for (int i = 0; i < HVCR_CUSTOM_OSD_NUM; i++)
    {
        nLen = strlen(m_osdcfg.StOSDItems[i].szOSD_CHAR);
        if (nLen == 0)
        {
            continue;
        }
        Gdiplus::RectF rec(50, 50 + 100 * i, 2000, 100);
        memset(tempText, 0, 256);
        char2wchar(tempText, m_osdcfg.StOSDItems[i].szOSD_CHAR);
        gdiGraphics.DrawString(tempText, -1, &gdifont, rec, &strformat, &br1);
    }

5.Image转Byte*

char* AddOSdInfo::Image2Byte(HGLOBAL mem, HBITMAP bmpTmpDraw)
{
    Gdiplus::Bitmap bm2((HBITMAP)bmpTmpDraw, NULL);
    CLSID Clsid2;
    GetEncoderClsid(L"image/jpeg", &Clsid2);//GetEncoderClsid函数在文末
    //bm2.Save(sNewPath2, &Clsid2);

    IStream *stream = NULL;
    HRESULT hr2 = CreateStreamOnHGlobal(mem, TRUE, &stream);
    bm2.Save(stream, &Clsid2);
    LARGE_INTEGER seekPos = {0};
    ULARGE_INTEGER imageSize;
    HRESULT hr = stream->Seek(seekPos, STREAM_SEEK_CUR, &imageSize);
    if (m_pBody)
    {
        delete m_pBody;
        m_pBody = NULL;
    }
    m_pBody = new BYTE[imageSize.LowPart];
    hr = stream->Seek(seekPos, STREAM_SEEK_SET, 0);
    hr = stream->Read(m_pBody, imageSize.LowPart, 0);
    m_nFileSize = imageSize.LowPart;
    
    //KOSA_fileWriteFile("SSSA.jpg", (UINT8*)m_pBody, imageSize.LowPart, false);
    return (char*)m_pBody;
}

6.封装的类

//头文件

#ifndef ADDOSDINFO_H
#define ADDOSDINFO_H
#include "kosa_file.h"
#include "kosa_dir.h"
#include <comdef.h>
#include <GdiPlus.h>
#include "Define.h"
#define MAXPICBUF                    6144000            // 最大图片缓冲区大小
class AddOSdInfo
{
public:
    
    ~AddOSdInfo();

    static AddOSdInfo* GetInstance();

    void SetOriginPicInfo(void *szBuf, DWORD dwBufSize, HVCR_OSD_CFG* osdcfg = NULL);

    bool JPG2Image(void *szBuf, DWORD dwBufSize);
    /*
    GetOsdPicInfo 返回图片的buffer, nFileLen图片长度
    */
    void* GetOsdPicInfo(Uint32* nFileLen);

    char* Image2Byte(HGLOBAL mem, HBITMAP bmpTmpDraw);

    void DrawImageEx(HDC hdc, Gdiplus::Image* pImage, RECT rc);

    void DrawInfo(HDC hdc, void *oldObj, HBITMAP bmpTmpDraw, HDC  hTempMemDC);

    Uint32 GetFileLen();

    void*  GetBuffer();

    void  SetOsdInfo(HVCR_OSD_CFG *osdcfg);
private:
    static AddOSdInfo* m_instance;
    
    AddOSdInfo();

    HGLOBAL        m_hImageMemPic;

    Gdiplus::Image* m_pImagePic;
    SIZE    m_sizePicOut;
    Uint32    m_nFileSize;
    void *    m_pBody;
    HVCR_OSD_CFG m_osdcfg;
    
};

#endif
 

//CPP文件

#include "AddOSdInfo.h"
#include "kosa_file.h"
#include "kosa_dir.h"
AddOSdInfo* AddOSdInfo::m_instance = NULL;
ULONG_PTR                        g_pGdiToken = NULL;
Gdiplus::GdiplusStartupInput    g_gdiplusStartupInput;

int GetEncoderClsid(const WCHAR * format, CLSID * pClsid)
{
    int nRet = -1;
    Gdiplus::ImageCodecInfo * pCodecInfo = NULL;
    UINT nNum = 0, nSize = 0;
    Gdiplus::GetImageEncodersSize(&nNum, &nSize);

    if (nSize < 0)
    {
        return nRet;
    }

    pCodecInfo = new Gdiplus::ImageCodecInfo[nSize];

    if (pCodecInfo == NULL)
    {
        return nRet;
    }

    Gdiplus::GetImageEncoders(nNum, nSize, pCodecInfo);

    for (UINT i = 0; i < nNum; i++)
    {
        if (wcscmp(pCodecInfo[i].MimeType, format) == 0)
        {
            *pClsid = pCodecInfo[i].Clsid;
            nRet = i;
            delete[] pCodecInfo;
            return nRet;
        }
        else
        {
            continue;
        }
    }

    delete[] pCodecInfo;
    return nRet;
}

bool char2wchar(wchar_t* pwsz, const char* psz)
{
    int len = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
    if (!pwsz)
    {
        return false;
    }
    memset(pwsz, 0, len + 1);
    MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, len);

    return true;
}


AddOSdInfo::AddOSdInfo()
{
    m_pImagePic = NULL;
    Gdiplus::GdiplusStartup(&g_pGdiToken, &g_gdiplusStartupInput, NULL);
    m_hImageMemPic = GlobalAlloc(GMEM_FIXED, MAXPICBUF);
    m_pBody = NULL;
    memset(&m_osdcfg, 0, sizeof(m_osdcfg));
}

AddOSdInfo *AddOSdInfo::GetInstance()
{
    if (m_instance == NULL)
    {
        m_instance = new AddOSdInfo;
        
    }
    return m_instance;
}


AddOSdInfo::~AddOSdInfo()
{
    if (m_hImageMemPic != NULL)
    {
        GlobalFree(m_hImageMemPic); 
        m_hImageMemPic = NULL; 
    }

    if (g_pGdiToken)
    {
        Gdiplus::GdiplusShutdown(g_pGdiToken);
        g_pGdiToken = 0;
    }

}

void* AddOSdInfo::GetOsdPicInfo(Uint32 *pSize)
{    
    *pSize = m_nFileSize;
    return m_pBody;
}

void AddOSdInfo::SetOriginPicInfo(void *szBuf, DWORD dwBufSize, HVCR_OSD_CFG* osdcfg)
{
    if (osdcfg)
    {
        memcpy(&m_osdcfg, osdcfg, sizeof(HVCR_OSD_CFG));
    }
    JPG2Image(szBuf, dwBufSize);

    HDC hdc = GetDC(NULL);
    HDC hTempMemDC = ::CreateCompatibleDC(NULL);
    HBITMAP bmpTmpDraw = ::CreateCompatibleBitmap(hdc, m_sizePicOut.cx, m_sizePicOut.cy);//hdc
    if (bmpTmpDraw == NULL) bmpTmpDraw = ::CreateCompatibleBitmap(hdc, m_sizePicOut.cx, m_sizePicOut.cy);
    if (bmpTmpDraw == NULL)
    {
        return;
    }
    HGDIOBJ oldObj = ::SelectObject(hTempMemDC, bmpTmpDraw);
    RECT rc;
    rc.left = 0;
    rc.top = 0;
    rc.right = m_sizePicOut.cx;
    rc.bottom = m_sizePicOut.cy;
    DrawImageEx(hTempMemDC, m_pImagePic, rc);

    DrawInfo(hTempMemDC, oldObj, bmpTmpDraw, hTempMemDC);

    Image2Byte(m_hImageMemPic, bmpTmpDraw);

    if (bmpTmpDraw != NULL)
    {
        DeleteObject(bmpTmpDraw);
        bmpTmpDraw = NULL;
    }
    if (hTempMemDC != NULL)
    {
        DeleteObject(hTempMemDC);
        hTempMemDC = NULL;
    }
}


// Jpg转换为Image;
bool AddOSdInfo::JPG2Image(void *szBuf, DWORD dwBufSize)
{
    HGLOBAL hMem = m_hImageMemPic;
    Gdiplus::Image** ppImage = &m_pImagePic;
    
    m_sizePicOut.cx = 0;
    m_sizePicOut.cy = 0;

    int nMaxLen = MAXPICBUF;
    BOOL bAlloc = FALSE;
    if (hMem == NULL)
    {
        bAlloc = TRUE;
        hMem = GlobalAlloc(GMEM_FIXED, nMaxLen);
    }

    if (*ppImage != NULL)
    {
        delete *ppImage;
        *ppImage = NULL;
    }

    if (dwBufSize != 0)
    {
        IStream* pStmBmp = NULL;
        CreateStreamOnHGlobal(hMem, FALSE, &pStmBmp);
        BYTE* pbyBmp = (BYTE *)GlobalLock(hMem);
        memset(pbyBmp, 0, nMaxLen);
        memcpy(pbyBmp, szBuf, dwBufSize);
        ::GlobalUnlock(hMem);
        *ppImage = Gdiplus::Image::FromStream(pStmBmp, FALSE);
        if ((*ppImage) != NULL)
        {
            m_sizePicOut.cx = (*ppImage)->GetWidth();
            m_sizePicOut.cy = (*ppImage)->GetHeight();
        }
    }

    if (bAlloc)
    {
        GlobalFree(hMem);
    }

    /*CLSID pngClsid;
    GetEncoderClsid(L"image/jpeg", &pngClsid);
    m_pImagePic->Save(L"Mosaic245.jpg", &pngClsid, NULL);*/

    return ((*ppImage) != NULL);
}


void*  AddOSdInfo::GetBuffer()
{
    return m_pBody;
}

Uint32 AddOSdInfo::GetFileLen()
{
    return m_nFileSize;
}

void  AddOSdInfo::SetOsdInfo(HVCR_OSD_CFG *osdcfg)
{
    memcpy(&m_osdcfg, osdcfg, sizeof(HVCR_OSD_CFG));
}

void AddOSdInfo::DrawInfo(HDC hdc, void *oldObj, HBITMAP bmpTmpDraw, HDC hTempMemDC)
{
#if 0
    HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);//CDC::GetCurrentFont(hdc);
    LOGFONT LogFont = { 0 };
    ::GetObject(hFont, sizeof(LOGFONT), &LogFont);
    ::DeleteObject(hFont);

    LogFont.lfHeight = -80; // 字体大小 
    hFont = CreateFontIndirect(&LogFont);
    HFONT hOldFont = (HFONT)::SelectObject(hdc, hFont);
    COLORREF clr = 0xFFFFFF;
    COLORREF clrOld = ::GetTextColor(hdc);
    SetBkMode(hdc, TRANSPARENT);
    ::SetTextColor(hdc, clr);
    
    int nLen = 0;
    for (int i = 0; i < HVCR_CUSTOM_OSD_NUM; i++)
    {
        nLen = strlen(m_osdcfg.StOSDItems[i].szOSD_CHAR);
        if (nLen == 0)
        {
            continue;
        }

        ::TextOut(hdc, 80, 100 * (i + 1), m_osdcfg.StOSDItems[i].szOSD_CHAR, nLen);
    }
    ::SetTextColor(hdc, clrOld);
    //char szTxt[168] = { 0 };
    //sprintf(szTxt, "ddddd大家好的萨芬硒鼓硒鼓", strlen("ddddd大家好的萨芬硒鼓硒鼓"));
    //::TextOut(hdc, 100, 100, szTxt, strlen(szTxt));
    //
#else
    
    //create font
    LOGFONTW lfont;
    memset(&lfont, 0, sizeof(lfont));
    int emSize = 70;
    lfont.lfHeight = -emSize; //   nHeight   注意使用负值,表示character height,  正值表示 cell height
    lfont.lfWeight = 400;//100;//FW_NORMAL,  //nWeight
    lfont.lfCharSet = GB2312_CHARSET;//;//ANSI_CHARSET
    wcscpy(lfont.lfFaceName, (L"微软雅黑"));  //   lpszFacename

    Gdiplus::Font gdifont(hdc, &lfont);
    
    Gdiplus::StringFormat strformat;
    strformat.SetAlignment(Gdiplus::StringAlignmentNear);//水平居左  
    strformat.SetLineAlignment(Gdiplus::StringAlignmentCenter);//垂直居中 
    Gdiplus::Font gFont(hdc, &lfont);
    Gdiplus::Color clr1(255, 255, 255);
    Gdiplus::SolidBrush    br1(clr1);
    Gdiplus::Graphics gdiGraphics(hdc);
    wchar_t tempText[256] = { 0 };
    int nLen = 0;
    for (int i = 0; i < HVCR_CUSTOM_OSD_NUM; i++)
    {
        nLen = strlen(m_osdcfg.StOSDItems[i].szOSD_CHAR);
        if (nLen == 0)
        {
            continue;
        }
        Gdiplus::RectF rec(50, 50 + 100 * i, 2000, 100);
        memset(tempText, 0, 256);
        char2wchar(tempText, m_osdcfg.StOSDItems[i].szOSD_CHAR);
        gdiGraphics.DrawString(tempText, -1, &gdifont, rec, &strformat, &br1);
    }
#endif
    /*
    wchar_t *sNewPath2 = L"..\\DevInterfaces\\HVCR_KD_V7_1\\tempDir\\temp.jpg";
    Gdiplus::Bitmap bm2((HBITMAP)bmpTmpDraw, NULL);
    CLSID Clsid2;
    GetEncoderClsid(L"image/jpeg", &Clsid2);//GetEncoderClsid函数在文末
    //bm2.Save(sNewPath2, &Clsid2);

    IStream *stream = NULL;
    HRESULT hr2 = CreateStreamOnHGlobal(m_hImageMemPic, TRUE, &stream);
    bm2.Save(stream, &Clsid2);
    LARGE_INTEGER seekPos = {0};
    ULARGE_INTEGER imageSize;
    HRESULT hr = stream->Seek(seekPos, STREAM_SEEK_CUR, &imageSize);
    if (m_pBody)
    {
        delete m_pBody;
        m_pBody = NULL;
    }
    m_pBody = new BYTE[imageSize.LowPart];
    hr = stream->Seek(seekPos, STREAM_SEEK_SET, 0);
    hr = stream->Read(m_pBody, imageSize.LowPart, 0);
    m_nFileSize = imageSize.LowPart;
    KOSA_fileWriteFile("SSSA.jpg", (UINT8*)m_pBody, imageSize.LowPart, false);
    */
    SelectObject(hTempMemDC, oldObj);
}

char* AddOSdInfo::Image2Byte(HGLOBAL mem, HBITMAP bmpTmpDraw)
{
    Gdiplus::Bitmap bm2((HBITMAP)bmpTmpDraw, NULL);
    CLSID Clsid2;
    GetEncoderClsid(L"image/jpeg", &Clsid2);//GetEncoderClsid函数在文末
    //bm2.Save(sNewPath2, &Clsid2);

    IStream *stream = NULL;
    HRESULT hr2 = CreateStreamOnHGlobal(mem, TRUE, &stream);
    bm2.Save(stream, &Clsid2);
    LARGE_INTEGER seekPos = {0};
    ULARGE_INTEGER imageSize;
    HRESULT hr = stream->Seek(seekPos, STREAM_SEEK_CUR, &imageSize);
    if (m_pBody)
    {
        delete m_pBody;
        m_pBody = NULL;
    }
    m_pBody = new BYTE[imageSize.LowPart];
    hr = stream->Seek(seekPos, STREAM_SEEK_SET, 0);
    hr = stream->Read(m_pBody, imageSize.LowPart, 0);
    m_nFileSize = imageSize.LowPart;
    
    //KOSA_fileWriteFile("SSSA.jpg", (UINT8*)m_pBody, imageSize.LowPart, false);
    return (char*)m_pBody;
}


void AddOSdInfo::DrawImageEx(HDC hdc, Gdiplus::Image* pImage, RECT rc)
{
    if (pImage)
    {
        Gdiplus::Graphics g(hdc);
        Gdiplus::ImageAttributes ImgAtt;
        ImgAtt.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
        g.DrawImage(pImage, Gdiplus::Rect(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top),
            0, 0, pImage->GetWidth(), pImage->GetHeight(),
            Gdiplus::UnitPixel, &ImgAtt, NULL, NULL);
    }
    else
    {
        //绘制背景
        HBRUSH hbrush = CreateSolidBrush(GetBkColor(hdc));
        ::FillRect(hdc, &rc, hbrush);
        ::DeleteObject(hbrush);
    }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值