由文本生成透明的文本图片

这个函数使用GDI plus实现将文本进行简单的排版,写入内存DC ,保存为透明的png图片。
文本格式自动根据行宽分行,并保持原有换行格式。


//一些定义
#define BITMAP_WIDTH = 256;
#define BITMAP_HEIGHT = 256;
#define MAX_TEXT_WIDTH  240 // must <= BITMAP_WIDTH
#define MAX_TEXT_HEIGHT  240 // must <= BITMAP_HEIGHT

//函数声明

void DrawFont(
   CStringW dstFilePath,//保存文件的全路径
   CStringW text, // 要写入的文本
   float size, // 字体大小
   UINT32 fgcolor = 0xffffffff,//字体颜色
   UINT32 bgcolor = 0x00000000,//背景颜色,透明mask用
   CStringW family = L"MS Pゴシック" //字体
   );

函数实现

void PiaResUtils::DrawFont(
 CStringW dstFilePath,
 CStringW text,
 float size,
 UINT32 fgcolor,
 UINT32 bgcolor,
 CStringW family)
{
 CStringW str = text;

 Status ret = Ok;
 FontFamily fontFamily(family);
 Font font(&fontFamily, size, FontStyleRegular, UnitPixel);
 Graphics g(0, 0);
 UINT32 width = BITMAP_WIDTH;
 UINT32 height = BITMAP_HEIGHT;
 INT32 pitch = INT32(width * 4);

 RectF fontRect;
 ret = g.MeasureString(L"函", -1, &font, RectF(0, 0, 0, 0), &fontRect);
 UINT32 fontH = (UINT32) (fontRect.Height);
 UINT32 fontW = (UINT32) (fontRect.Width);
 UINT32 maxCharInLine = (UINT32)(MAX_TEXT_WIDTH/fontW);

 std::auto_ptr<Bitmap> bitmap(new Bitmap(width, height, &g));
 {
  std::auto_ptr<Graphics> g(Graphics::FromImage(bitmap.get()));
  g->Clear(Color(ARGB(bgcolor)));
  g->SetTextRenderingHint(TextRenderingHintAntiAlias);

  PointF pointF;
  pointF.X = (BITMAP_WIDTH - MAX_TEXT_WIDTH)/2;
  pointF.Y = (BITMAP_HEIGHT - MAX_TEXT_HEIGHT)/2;
  SolidBrush solidBrush = Color(ARGB(fgcolor));

  UINT32 pos = 0;
  UINT32 len = 0;
  RectF rect;
  UINT32 strW = 0;
  CStringW temp = L"";
  while (str != L"") {
   pos = str.Find(L'/n');
   len = str.GetLength();
   if (pos == -1) {
    pos = str.GetLength();
    if (pos <= maxCharInLine) {
     temp = str;
     str = L"";
    }
    else {
     pos = maxCharInLine;

     BOOL ret = FALSE;
     while (!ret) {
      temp = str.Left(pos);
      ret = g->MeasureString(temp, -1, &font, RectF(0, 0, 0, 0), &rect);
      if ((UINT32) (rect.Width) <= MAX_TEXT_WIDTH) {
       pos += 1;
       if (pos > len) {
        pos = len;
        ret = TRUE;
       }
      }
      else {
       pos -= 1;
       ret = TRUE;
      }
     }

     temp = str.Left(pos);
     str = str.Right(len - pos);
    }
   }
   else if (pos <= maxCharInLine) {
    temp = str.Left(pos);
    if (len - pos - 1 > 0) {
     str = str.Right(len - pos - 1);
    }
    else {
     str = L"";
    }
   }
   else if (pos > maxCharInLine) {
    UINT32 posTo = maxCharInLine;
    BOOL ret = FALSE;
    while (!ret) {
     temp = str.Left(posTo);
     ret = g->MeasureString(temp, -1, &font, RectF(0, 0, 0, 0), &rect);
     if ((UINT32) (rect.Width) <= MAX_TEXT_WIDTH) {
      posTo += 1;
      if (posTo > pos) {
       posTo = pos;
       ret = TRUE;
      }
     }
     else {
      posTo -= 1;
      ret = TRUE;
     }
    }

    temp = str.Left(posTo);
    str = str.Right(len - posTo);
   }

   g->DrawString(temp, -1, &font, pointF, &solidBrush);
   
   pointF.Y += fontH;
   if ((UINT32)(pointF.Y + fontH )> MAX_TEXT_HEIGHT){
    str = L"";
   }
  }
 }
 {
  Rect rect(0, 0, width, height);
  BitmapData data;
  Status ret = bitmap->LockBits(&rect, ImageLockModeRead, PixelFormat32bppARGB, &data);
  if (ret != Ok) {
   throw std::exception("Gdiplus::Bitmap::LockBits failed.");
  }

  bitmap->UnlockBits(&data);
 }

 CLSID clsid;
 GetEncoderClsid(L"image/png", &clsid);
 bitmap->Save(dstFilePath, &clsid);
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值