由于要控制硬件,需要把矢量的漢字轉化為點陣信息寫入eprom或在液晶屏上顯示,因此用Delphi寫了如下的函數,可以把指定的一個漢字(兩個字符)轉化為點陣信息保存到文件,每個點對應一個位,有文字信息該位為1,否則為0。
目前該函數可以生成指定的大小漢字并讀取成點陣字模信息保存到文件。
如ConvertToMatrix(Pchar('北'),6,18,'Font.dat')將生成12*18點陣文件Font.dat,其中保存漢字‘北’的字模。文件格式是從上到下,先行后列,如下圖,第一行保存00 00,第二行是90 00 (均是16進制,余下個行類推)
//轉化一個漢字為點陣信息Text為一個漢字,ChrWidth是字符寬,漢字是兩個字符大小,所有如果要生成寬是12的漢字則ChrWidth為6,ChrWidth目前最多是8,因為大多數的硬件使用的點陣信息是16以下ChrHeight是漢字的高,SaveFileName是保存該漢字點陣信息的文件名。 function ConvertToMatrix(Text:PChar; ChrWidth,ChrHeight:Byte; SaveFileName:Pchar):Bool; type PBITMAPINFO=^TBitmapInfo; var TempBmp:TBitmap; lpvSBits,lpvDBits:Pchar; dOffset,sOffset:integer; DC:HDC; TheFont: HFont;
BMIInfo:PBITMAPINFO; DS: TDIBSection; BMIbuf:array[0..2047]of byte;
i,j:integer;//循環控制
wData:WORD;//保存字體每行的點陣信息,最多16位,不足16位忽略多余的高位
MemoryStream:TMemoryStream;
begin //大于一個字退出 if Length(Text)>2 then begin ShowMessage('請轉化一個漢字!'); Result:=False; Exit; end; //參數合理否 if (ChrWidth=0) or (ChrHeight=0) or (SaveFileName = '') then begin ShowMessage('參數錯誤!'); Result:=False; Exit; end; //建立流 MemoryStream:=TMemoryStream.Create; //建立臨時文件 TempBmp:=TBitmap.Create; //設定為256色 TempBmp.PixelFormat:= pf8bit; //設定圖寬度 TempBmp.Width:=ChrWidth * Length(Text); //設定圖高度 TempBmp.Height:= ChrHeight; //得到BMP文件HDC DC:=TempBmp.Canvas.Handle; //建立邏輯字體 TheFont := CreateFont(ChrHeight,ChrWidth, 0, 0, 400, 0, 0, 0, GB2312_CHARSET, Out_Default_Precis, Clip_Default_Precis, Default_Quality, Default_Pitch OR FF_SCRIPT, 'script'); //指定字體給DC SelectObject(DC,TheFont); //寫入指定字符串 TextOut(DC,0,0,Pchar(Text),Length(Text)); //釋放邏輯字體 DeleteObject(TheFont);
//取得Bmp信息到lpvSBits BMIInfo:=PBITMAPINFO(@BMIbuf); //分配內存 lpvSBits:=AllocMem(TempBmp.Width*TempBmp.Height); lpvDBits:=AllocMem(TempBmp.Width*TempBmp.Height); //建立程序屏幕兼容的DC DC := CreateCompatibleDC(0); //返回指定的BMP信息到DS中保存 GetObject(TempBmp.Handle, SizeOf(DS), @DS); //讀取頭信息 BMIInfo.bmiHeader:=ds.dsBmih; //讀入DIB GetDIBits(DC, TempBmp.Handle, 0, ds.dsBmih.biHeight,lpvSBits, BMIInfo^ , DIB_RGB_COLORS); //倒置圖像 for i:=0 to TempBmp.Height-1 do begin sOffset:=i*TempBmp.Width; dOffset:=(TempBmp.Height-i-1)*TempBmp.Width; CopyMemory(lpvDBits+dOffset,lpvSBits+sOffset,TempBmp.Width); end; //保存文件 for i:=0 to TempBmp.Height-1 do begin wData:=0; for j:=0 to TempBmp.Width-1 do begin //ShowMessage(inttostr(ord((lpvDBits+i*TempBmp.Width+j)^))); if ord((lpvDBits+i*TempBmp.Width+j)^)=0 then begin wData:=(wData shl 1)OR 1; end else begin wData:=(wData shl 1)OR 0; end; end; MemoryStream.Write(wData,SizeOf(wData)); end;
MemoryStream.SaveToFile(SaveFileName); MemoryStream.Free; //TempBmp.SaveToFile('temp.bmp')可刪除,存'temp.bmp'文件的目的只是為對比察看 TempBmp.SaveToFile('temp.bmp'); TempBmp.Free; result:=True;
end;
附:本文全部為原創內容,如果您使用中對程序做了改動請發給作者一分webmaster@daheng-image.com;引用是請注明作者Thermometer和Email,謝謝。
|