现在的位置: 首页 > 综合 > 正文

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

2013年08月21日 ⁄ 综合 ⁄ 共 2983字 ⁄ 字号 评论关闭

这个函数使用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);
}

 

抱歉!评论已关闭.