转:使用freetype生成字体图片FireMonkey效率问题

下面是测试代码,经过优化后主要是重设png图像大小,严重影响速度,一万字可能需要5秒左右,解决方案,自己写一个png文件的解析生成单元,png格式文件还是比较简单的,如果单纯生成一个可调用的字体png图像文档,只需要包含必要的四个区块就可以了,(其实是两个,其他两个一个是固定的头部信息,一个是固定的尾部信息),关于png分析网上文档很多,不做分析,贴出原始FireMonkey的TBitmap测试代码,需要注意的是要使用delphi 10.2版本以上,因为其他低版本TBitmap不支持多线程,再主线程调用也会严重影响界面元素,特别是再手机设备上,就算成功了,图像也会莫名其妙的出现一些污点,不适合生成字体使用........

 

unit Unit1;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo, FMX.StdCtrls, PXL.Fonts.FreeTypeH, Unit2;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    FTLib: PFT_Library;
 
    FFTFace: PFT_Face;
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.fmx}
 
uses DateUtils ;
 
procedure TForm1.Button1Click(Sender: TObject);
var
 text:string ;
 i:Integer ;
 lvCharUnicode:Integer ;
 slot:PFT_GlyphSlot ;
 bitmap : FT_Bitmap;
 lvBMPBuf: PByteArray;
 rdb:TBitmapData;
 s:TAlphaColor;
 png:TBitmap ;
 w,h,t,x,y:Integer ;
begin
 text:=Memo1.Text ;
 if text = '' then
 begin
   Exit ;
 end;
 Caption:=IntToStr(Length(text)) ;
 t:=GetTickCount ;
 png:=TBitmap.Create(1024,1024) ;
 png.Map(TMapAccess.Write,rdb) ;
 try
 if FT_Set_char_size(FFTFace, 0, 64 shl 6, 0,0) <> 0 then
 begin
   raise Exception.Create('字体大小设置失败...');
   Exit ;
 end;
 for I := 1 to Length(text) do
 begin
   lvCharUnicode:= ord(text[i]);
   if FT_Load_Char(FFTFace,lvCharUnicode,FT_LOAD_DEFAULT) <> 0 then
   begin
    raise Exception.Create('字体解析失败...');      Exit ;
 
   end;
   if FFTFace.glyphslot.format = FT_GLYPH_FORMAT_OUTLINE then
   begin
    if FT_Outline_Embolden(FFTFace.glyphslot.outline,2 shl 6) <> 0 then
    begin
      raise Exception.Create('字体加粗失败...');      Exit ;
    end;
   end;
   if FT_Render_Glyph(FFTFace.glyphslot,FT_RENDER_MODE_NORMAL)<>0 then
   begin
     raise Exception.Create('生成位图失败...');
     Exit ;
   end;
  slot:=FFTFace.glyphslot ;
  bitmap:=slot.bitmap ;
  lvBMPBuf:= PByteArray(bitmap.buffer);      //得到图像数据
  w:=bitmap.width ;  //字的宽度
  h:=bitmap.rows ;   //字的高度
  if (x=0) or (h=0) then
  begin
    Continue ;
  end;
  png.Resize(w,h);   //重新设置png大小, 这里严重影响速度
  for y := 0 to h - 1 do
  for x := 0 to w - 1 do
  begin
   TAlphaColorRec(s).R:=$ff;
   TAlphaColorRec(s).G:=$ff;
   TAlphaColorRec(s).B:=$ff;
   TAlphaColorRec(s).A:=lvBMPBuf[x + w * y];
   rdb.SetPixel(x,y,S);
  end;
 
 end;
 ShowMessage(IntToStr(GetTickCount - t));
 finally
 png.Unmap(rdb);
 png.Free ;
 end;
 
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
 if not FreeTypeLibraryInitialized then
 begin
    raise Exception.Create('加载DLL失败....');
 end;
 
 if FT_Init_FreeType(FTLib) <> 0 then
 begin
   raise Exception.Create('初始化失败');
   Exit ;
 end;
 
 if FT_New_Face(FTLib, PAnsiChar(AnsiString(ExtractFilePath(ParamStr(0))+'方正粗雅宋_GBK.TTF')), 0, FFTFace) <> 0 then
 begin
   raise Exception.Create('加载字体失败...');
   Exit ;
 end;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
 FT_Done_FreeType(FTLib) ;
end;
 
end.
————————————————
版权声明:本文为CSDN博主「zplovepkk」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zplovepkk/java/article/details/73733576

 


版权声明:本文为CSDN博主「zplovepkk」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zplovepkk/java/article/details/73733576

posted @ 2020-04-25 16:58  lai1322  阅读(378)  评论(0编辑  收藏  举报