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