• 转:使用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

  • 相关阅读:
    python2.7 使用super关键词 报错 TypeError: must be type, not classobj 解决办法
    ACM_高次同余方程
    既然选择了、再怎么艰难也要走下去
    ACM_扩展欧几里德算法
    Codeforces Round #328 (Div. 2)_B. The Monster and the Squirrel
    Codeforces Round #328 (Div. 2)_A. PawnChess
    HDU_5523Game
    POJ_2769同余问题
    poj1258prim算法
    最小生成树—prim算法
  • 原文地址:https://www.cnblogs.com/timba1322/p/12773911.html
Copyright © 2020-2023  润新知