注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

珠海渔郎之电子网档

项目管理 + 程序开发 + Delphi + 电脑应用 + 数码 + 进化感悟

 
 
 

日志

 
 

[存档2006-6-20]如何提取RTF中的图片  

2009-11-02 18:11:35|  分类: Delphi |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

如何提取RTF中的图片

来自:lanyaoshi, 时间:2006-6-1 21:37:00, ID:3459681

已知道RTF格式中的图片文件是以metafile格式存在的,以{\pict\wmetafile8\picw423\pich688\picwgoal240\pichgoal390开始,然后是metafile的HEX字符串,但不知道如何将这一大段HEX字符串保存为BMP文件或metafile格式文件呢?例如下面是一段包含图片的RTF文件的内容: {\rtf1\ansi\ansicpg936\deff0{\fonttbl{\f0\fnil\fcharset134 \'cb\'ce\'cc\'e5;}} \viewkind4\uc1\pard\lang2052\f0\fs18{\pict\wmetafile8\picw423\pich688\picwgoal240\pichgoal390 010009000003160300000000f102000000000400000003010800050000000b0200000000050000 000c021b001100030000001e000400000007010400f1020000410b2000cc001a00100000000000 1a0010000000000028000000100000001a00000001000800000000000000000000000000000000 00000000000000000000000000ffffff00fbfcfd00ced2ec00a4aee80095a3f100c7cbe300eff0 f900e4e5eb006472d1005c68c7009aa0cf00949acd004c59c300273fde00465bd800bdc1df00e1 e2e700848bc200fdfdfe007f86c300122be000051bd700a5a9cb00f4f4f5007a8ae2003b46ac00 0f1fac00dbdce400354be0006b72ab00b9bedb000c25dd000112b900868aaf008898e100182cca 00777ca800ebedf3004f569700f8f9fb005d71de000c21c800636aa5005065db00091dbf002c35 9000fbfbfc00424a94007282de00424a8d0008128d000210a800a5acda00c8cad8004954bb001a 27a400dee1ea00303ba900daddee003f4fc300f7f7f900202da900d1d3e400d6d9e90000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101010101010101010101010101010101 010101013d3f10402801010101010101010126222e3e0a090d1713010101010101081a343a3b01 133b3c2b3d010101012f3721381101010101391b25130101013516212201010101011329333601 0113091633080101010101011934250101282c2a3001010101010101312d32130128292a2b0101 01010101022c2d2e2f0113232425010101010101260e2127010101101d1e0101010101011f2021 2201010118191a1301010101130d161b1c01010101110f12130101011415161701010101010108 090a0b0c0d0e0f1001010101010101010203040504060701010101010101010101010101010101 010101010101010101010101010101010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101010101010101010101010101010101 010101010101040000002701ffff030000000000 } \par }

解答: Copyright (C) Kingron, 2006 实际上很简单,RTF中对所有的二进制数据均采用HEX化的处理,所以只要把HEX转成二进制即可。也就是把那些HEX字符串,每两个作为一个整体,然后转换成二进制对应的字符,并存储下来,就是原始的数据!例如把上面的十六进制转换代码如下

[pas] procedure AnsiSotrPicToWMF(const FileName: string; Width, Height: Integer; Data: string); { 本函数用于把RTF中WMF文件ANSISTORPIC存储格式的字符串转换成对应的WMF文件 FileName表示输出的WMF文件名 Width,Height表示WMF文件的宽度和高度,即RTF中的{picwN和{pichN的N的值 Data: ANSISTORPIC格式的数据,可以包含回车,程序自动处理 } const WMFKey = Integer($9AC6CDD7); WMFWord = $CDD7; HundredthMMPerInch = 2540; type TMetafileHeader = packed record Key: Longint; Handle: SmallInt; Box: TSmallRect; Inch: Word; Reserved: Longint; CheckSum: Word; end;

function ComputeAldusChecksum(var WMF: TMetafileHeader): Word; type PWord = ^Word; var pW: PWord; pEnd: PWord; begin Result := 0; pW := @WMF; pEnd := @WMF.CheckSum; while Longint(pW) < Longint(pEnd) do begin Result := Result xor pW^; Inc(Longint(pW), SizeOf(Word)); end; end;

var PureText : string; buf : PChar; Len : DWORD; wmf : TMetafileHeader; fs : TFileStream; begin /// 去掉回车换行之类的数据 PureText := StringReplace(Data, #13#10, '', [rfReplaceAll]);

/// 计算转换后的长度,并申请缓冲区内存 Len := Length(PureText) shr 1;

/// WMF头信息 FillChar(wmf, SizeOf(wmf), 0); with WMF do begin Key := WMFKEY; Inch := 96; { WMF defaults to 96 units per inch } with Box do begin Right := MulDiv(Width, WMF.Inch, HundredthMMPerInch); Bottom := MulDiv(Height, WMF.Inch, HundredthMMPerInch); end; CheckSum := ComputeAldusChecksum(WMF); end;

GetMem(buf, Len); fs := TFileStream.Create(FileName, fmCreate); try /// 转换ANSISTORPIC格式为BIN格式 HexToBin(PChar(PureText), Buf, Len);

fs.Write(wmf, SizeOf(wmf)); fs.Write(buf^, Len); finally FreeMem(buf); fs.Free; end; end;

procedure TForm1.Button1Click(Sender: TObject); const fn = 'C:\o.wmf'; begin AnsiSotrPicToWMF(fn, 423, 688, Memo1.Text); end;

[/pas]其中Memo1的Text就是那些十六进制的字符,注意不要包括RTF的那些格式数据。上面转换得到的图片如下: ,和RTF中是一样的!

  评论这张
 
阅读(877)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017