编程实现文本文件到图像文件的转化

I

import

Unregistered / Unconfirmed
GUEST, unregistred user!
编程实现文本文件到图像文件的转化
 
--------------------------------------------------------------------------------
   经常上网的朋友在收发电子邮件时,由于双方的内码不一致或者操作系统有差异,经常会出现乱码。有人就提出了一种解决的途径,即在画笔等图像编辑软件里输入,再存为图片,然后以图像形式发送邮件。但是在图像编辑软件里输入文字总有这样那样的不便之处,而直接把文本文件转换成图像的软件又不多见,下面我们就“自己动手,丰衣足食”,用Delphi编程来实现它。
  为了保证跨中英文平台使用,我们必须在程序中自带字库,这里我选择UCDOS中的中文点阵字库hzk16和ASC字符字库asc16,首先我们要把它们编译成资源。用任何一个文本编辑器编辑hzk.rc如下:
  201 HZK16 DISCARDABLE “Hzk16"
  202 ASC16 DISCARDABLE “Asc16"
  然后把UCDOS中的两个字库hzk16和asc16拷入当前目录中,在DOS环境下运行brcc32 hzk.rc,其中brcc32.exe位于Delphi安装目录中的bin目录下,如果正常的话,应该在当前目录中生成一个资源文件hzk.res。
  下面我们在Delphi中建立一个工程,命名为txt2bmp,命名主Form为MainForm,在TMainForm声明之前加入以下内容:
  type
  ByteArray = Array [0..0] of byte;
  PByte = ^ByteArray;
  在TMainForm的Private段中加入以下内容:
  hhzk : HGlOBAL;
  //汉字点阵资源句柄
  hasc : HGLOBAL;
  //ASC字符点阵资源句柄
  phzk : PByte;
  //汉字点阵资源指针
  pasc : PByte;
  //ASC字符点阵资源指针
  SFile, DFile : string;
  //转换的源文件和目的文件名
  procedure HandleRes; //处理引入的资源
  procedure Convert;
  //Txt2Bmp转换函数
  procedure WriteLine(str: string; x,y: integer; Can: TCanvas)
  //在图像的Canvas中写入一行汉字
  为了节省篇幅,SFile和DFile的设置请读者自行完成,我是用一个OpenDialog和一个SaveDialog来实现的,设置好SFile和DFile以后,直接调用Convert即可。下面我们来完成上面三个主要的函数:
  首先来定位程序中的点阵资源,即完成HandleRes函数,程序段如下:
  procedure TMainForm.HandleRes;
  var
  hres : HRSRC;
  begin
  hres := FindResource(0,PChar(201),“HZK16”);
   //查找汉字点阵资源
  if hres <> 0 then begin
  hhzk := LoadResource(0,hres);
  //载入汉字点阵资源
  if hhzk <> 0 then begin
  phzk := LockResource(hhzk);
  //锁定,得到资源指针
  end;
  end;
  hres := Find Resource(0,PChar(202),“ASC16”);
  //查找ASC字符资源
  if hres <> 0 then begin
  hasc := LoadResource(0,hres);
  //载入ASC字符资源
  if hasc <> 0 then begin
  pasc := LockResource(hasc);
  //锁定,得到资源指针
  end;
  end;
  if (phzk = nil) or (pasc = nil) then begin
  MessageDlg(“Can not load resource!”#10#13“Program stopped!”,
  mtWarning,[mbOk],0);
  Application.Terminate;
  end;
  end;
  为了保证资源正确释放,在FormCreate事件中加入如下代码:
  hhzk := 0;
  hasc := 0;
  phzk := nil;
  pasc := nil;
  SFile := “”;
  DFile := “”;
  HandleRes;
  在FormDestroy事件中加入以下代码:
  if hhzk <> 0 then FreeResource(hhzk);
  if hasc <> 0 then FreeResource(hasc);
  接着我们来编写Convert函数,源代码如下:
  procedure TMainForm.Convert;
  var
  tf : TextFile;
  StrLst : TStringList;
  buf : string;
  w,h,i : integer;
  bmp : TBitMap;
  begin
  StrLst := TStringList.Create;
   //用来存为文件内容
  AssignFile(tf,SFile);
  Reset(tf); //打开源文件
  while not Eof(tf) do begin
  ReadLn(tf,buf);
  //循环读入文件内容
  for i := 1 to Length(buf) do begin
  //把TAB键、回车、换行转为空格
  if (buf = #9) or (buf = #10) or (buf = #13)
  then buf := ' ';
  end;
  StrLst.Add(buf);
  end;
  CloseFile(tf);
  //以下代码计算bmp文件尺寸,由于是16点阵字库,
  //每个字符高度为16,宽度为8,每行间距取为4
  h := StrLst.Count*20; //bmp文件高度
  w := 0;
  for i := 0 to StrLst.Count-1 do begin//计算最长一行字符数
  if w   end;
  w := w*8;//bmp文件宽度
  bmp := TBitMap.Create;
  //创建bmp对象
  bmp.Monochrome := true;
  //选择创建黑白图像,缩小尺寸
  //设定尺寸,预留页边距
  bmp.Height := h + 60;
  bmp.Width := w + 60;
  for i := 0 to StrLst.Count-1 do begin//调用WriteLine写入一行
  
  WriteLine(StrLst,30,30+i*20,bmp.Canvas);
  end;
  bmp.SaveToFile(DFile);
  //bmp文件存盘
  Image1.Picture.Bitmap.Assign(bmp);//此句需在Form上放置Image1,查看结果
  bmp.Free;
  StrLst.Free;
  end;
  下面是最后一个函数WriteLine,其中有关点阵定位的计算,请参见以前DOS下显示汉字的有关文章。
  procedure TMainForm.WriteLine(str: string; x, y: integer; Can: TCanvas);
  var
  i,m,n,k : integer;//循环变量
  leng : integer;//字符串长度
  off : integer;//点阵偏移
  begin
  i := 1;
  leng := Length(str);
  //计算字符串长度
  while(i<=leng) do begin
  //判断是否是汉字,汉字占两行
  if (i   and boolean(byte(str[i+1]) and $80) then begin
  //计算汉字点阵偏移量
  off := ((byte(str)-$a1) and $7f) * 94 + ((byte(str[i+1])-$a1) and $7f);
  off := off * 32;
  //在画布上描绘一个汉字
  for m := 0 to 15 do begin
  for n := 0 to 1 do begin
  for k := 7 downto 0 do begin
  if boolean(phzk[off+m*2+n] and (1 shl k)) then begin
  Can.Pixels[x+n*8+7-k,y+m] := 1;
  end;
  end;
  end;
  end;
  inc(x,16);
  inc(i,2);
  end else begin //不是汉字
  off := byte(str)*16;//计算ASC字符点阵偏移
  //在画布上描绘一个ASC字符
  for m := 0 to 15 do begin
  for k := 7 downto 0 do begin
  if boolean(pasc[off+m] and (1 shl k)) then begin
  Can.Pixels[x+7-k,y+m] := 1;
  end;
  end;
  end;
  inc(x,8);
  inc(i);
  end;
  end;
  end;
  至此,本程序的主体部分已经基本完成,具体细节可参见源代码(http://home.etang.com/xd_w/software/txt2bmp.zip),程序运行界面如图所示。本程序在Delphi4.0,PWIN98,Celeron366上调试通过。本程序生成bmp文件后,转换成gif文件,将进一步减小尺寸。另外本程序稍加改进即可用于在英文平台上显示中文文本,进一步加入BIG5和GB码的转换码表,还可以作到直接转换BIG5码文件,有兴趣的读者可进一步修改,到时候别忘了给我一份就行了。
  (上海 XD.W)
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
709
import
I
顶部