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);
}
}