实现通过GDI+将输入的字符串保存为背景透明的图片的示例代码


【1】头文件




#ifndef  _AFXSTD_EF4A7E9D_ECEF_4D13_B0AD_ADEB38D1E347_INCLUDE_H_
#define _AFXSTD_EF4A7E9D_ECEF_4D13_B0AD_ADEB38D1E347_INCLUDE_H_


#if _MSC_VER > 1000
#pragma once
#endif


#include <string>
using namespace std;

#include <gdiplus.h>

//==================================CTextToImage==================================
/// @brief 文本转图片
///
/// 将文本字符串转成透明图片
//================================================================================
class CTextToImage
{
public:
CTextToImage();
CTextToImage(wstring &strText, wstring pFontName = L"宋体", float fontSize=12, DWORD pColor=0x000000FF, int fontStyle=0);
~CTextToImage();

public:
void SetString(wstring &strText);
int GetFontCount();
void GetFontNameArr(WCHAR **pFontNameArr, int numSought, int *pNumFound);
void SetFontName(wstring &fontName);
void SetFontSize(float fontSize);
void SetFontColor(DWORD color);
void SetFontStyle(int fontStyle);
void SaveToImage(HWND hWnd, wstring &strPicPath );

private:
wstring *m_pStrText; //文本
WCHAR *m_pFontName; //字体名称
Gdiplus::Color *m_pFontColor; //文本的颜色
float m_FontSize; //字号
int m_FontStyle; //字体效果规则、粗体、斜体、粗斜体、下划线、强调线
};


#endif //!_AFXSTD_EF4A7E9D_ECEF_4D13_B0AD_ADEB38D1E347_INCLUDE_H_


【2】cpp文件




#include "stdafx.h"
#include "Caption.h"

using namespace Gdiplus;

CTextToImage::CTextToImage()
{
m_pStrText = new wstring;
m_pFontColor = new Gdiplus::Color(Gdiplus::Color::Black);
m_pFontName = new WCHAR[32];
wcscpy_s(m_pFontName, 32, L"宋体");
m_FontSize = 12;
m_FontStyle = Gdiplus::FontStyleRegular;
}

CTextToImage::CTextToImage( wstring &strText, wstring pFontName /*= "宋体"*/, float fontSize/*=12*/, DWORD pColor/*=0x000000FF*/, int fontStyle/*=0*/ )
{
new(this)CTextToImage();

*m_pStrText = strText;
wcscpy_s(m_pFontName, 32, pFontName.c_str());
m_FontSize = fontSize;
m_FontStyle = fontStyle;
m_pFontColor->SetFromCOLORREF(pColor);
}

CTextToImage::~CTextToImage()
{
if (NULL != m_pStrText)
{
delete m_pStrText;
}

if (NULL != m_pFontColor)
{
delete m_pFontColor;
}
if (NULL != m_pFontName)
{
delete []m_pFontName;
}
}

void CTextToImage::SetString(wstring &strText )
{
if (NULL == m_pStrText)
{
return;
}

*m_pStrText = strText;
}

bool GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0, size = 0;

Gdiplus::GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure

Gdiplus::ImageCodecInfo* pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));

Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);
bool found = false;
for (UINT ix = 0; !found && ix < num; ++ix)
{
if (_wcsicmp(pImageCodecInfo[ix].MimeType, format) == 0)
{
*pClsid = pImageCodecInfo[ix].Clsid;
found = true;
break;
}
}

free(pImageCodecInfo);
return found;
}

void CTextToImage::SaveToImage(HWND hWnd, wstring &strPicPath )
{
if (NULL == m_pStrText || NULL == m_pFontColor)
{
return;
}

Gdiplus::FontFamily fontFamily(m_pFontName);
Gdiplus::Font font(&fontFamily, m_FontSize, m_FontStyle, Gdiplus::Unit::UnitPoint);
Gdiplus::SolidBrush solidBrush(*m_pFontColor);
Gdiplus::Graphics graphics(hWnd);

//Gdiplus::StringFormat stringformat;
//stringformat.SetTrimming(StringTrimming::StringTrimmingEllipsisWord);

//字体边沿平滑处理
graphics.SetTextRenderingHint(Gdiplus::TextRenderingHint::TextRenderingHintAntiAlias);

//【1】计算字符串的尺寸
Gdiplus::RectF boundingBox(0, 0, 0, 0);
graphics.MeasureString(m_pStrText->c_str(), -1, &font, Gdiplus::PointF(0, 0), &boundingBox);

//【2】创建bitMap
Gdiplus::SizeF size;
boundingBox.GetSize(&size);
Gdiplus::Bitmap bitmap((int)size.Width, (int)size.Height, PixelFormat32bppARGB);
Gdiplus::Graphics g(&bitmap);

//【3】绘制文本
g.DrawString(m_pStrText->c_str(), -1, &font, Gdiplus::PointF(0, 0), &solidBrush);

CLSID clsID = GUID_NULL;
wchar_t ext[_MAX_EXT] = {0};
wchar_t format[_MAX_EXT] = {L"image/"};

_wsplitpath_s(strPicPath.c_str(), NULL, 0, NULL, 0, NULL, 0, ext, _MAX_EXT);
wcscat_s(format, _MAX_EXT, ext + 1);
if (GetEncoderClsid(format, &clsID))
{
bitmap.Save(strPicPath.c_str(), &clsID, NULL);
}
}

void CTextToImage::SetFontColor( DWORD color )
{
m_pFontColor->SetFromCOLORREF(color);
}

void CTextToImage::GetFontNameArr(WCHAR **pFontNameArr, int numSought, int *pNumFound)
{
if (NULL == pFontNameArr || numSought < 1)
return;

//获取字体名称列表
FontFamily *pFontFamily = new FontFamily[numSought];

InstalledFontCollection installedFontCollection;
installedFontCollection.GetFamilies(numSought, pFontFamily, pNumFound);

for(int j=0; j<*pNumFound; j++)
{
pFontFamily[j].GetFamilyName(pFontNameArr[j]);
}

delete[] pFontFamily;
}

int CTextToImage::GetFontCount()
{
InstalledFontCollection installedFontCollection;
return ( installedFontCollection.GetFamilyCount() );
}

void CTextToImage::SetFontName( wstring &fontName )
{
wcscpy_s(m_pFontName, 32, fontName.c_str());
}

void CTextToImage::SetFontSize( float fontSize )
{
m_FontSize = fontSize;
}

void CTextToImage::SetFontStyle( int fontStyle )
{
m_FontStyle = fontStyle;
}


【3】测试代码




CTextToImage  txtImage(wstring(L"dafsdfasd"));
txtImage.SaveToImage(m_picCtrl, wstring(L"D:\\filterTest\\txtTojpg.png"));


说明:保存为png格式的图片才可以带透明通道!