提取word图形文档

这是某人以前开发某某系统的文档,权当一点积累贴出来.
虽然很粗劣,但是毕竟算点经验,在开发过程中也费了不少精力。

矢量图形开发设计文档

 

技术背景

在××系统的预案中有大量的图形信息,用来存储各种建筑平面图,剖面图,结构图以及各种作战计划图,作战路线图等等。这些图形信息是在word中用其图形工具绘制而成。在××软件的实际应用中,需要将这些图形信息传输到远程PDA终端显示。一般情况下,一张图片使用jpeg格式压缩需要100kB左右的空间,在无线传输过程中,带宽只有35k,很难实时传送图形信息,为了尽可能地压缩数据量,提高传输效率和准确率,结合图形自身特点,采用矢量编码代替jpeg编码,图形数据量可以压缩到只有5k左右,极大地节省了数据占有空间和传输时间。

Microsoft word提供了非常强大的接口功能,有专门的VBA编程供用户自定义控制wordDelphi中自带了已经封装好的针对office系列的servers组件和ole接口控制。这对提取图形数据提供了更多便利和可靠。

 

技术方案

在重点单位的平面图,周围环境图和各建筑层作战力量部署图中。基本组成是许多直线绘制的建筑框架,曲线绘制的各种行动线路,由组合图元绘制的各种标识,艺术字和文本框标识的各种说明标记。

delphi和vb中都有office控件,可以提取word中存储的各种信息.我们使用一个工具将word中的信息提出来形成矢量图形文件,作为重现和传输的信息载体;图像重现需要在pda和移动笔记本上实现,针对的是矢量图形,矢量图形的定义见附件1;图像的传输主要是无线传输,在软件的通讯部分得以解决,通讯协议见附件2.

Word文件中图形提取解决办法:

提取各种确定图形元素的形状,大小,位置,等主要外观信息。例如:提取直线的标识,位置,大小,线宽,颜色,旋转角度,走向和线头线尾形状;曲线的标识、节点个数及其位置,线宽,颜色等信息;艺术字和文本框的大小、位置、文字内容、字体大小和颜色。提取图片的大小,位置,图像编号和源文件名称;提取自动图形的大小,位置,图形类型和调节器值;取消所有的组合,让其变成普通的图形元素以便用普通方法提取。最后封装这些简单数据进行存储,传输。接受方依据接受的数据,分析重新在本地绘制出完全一样的图形。大幅度提升了执行和传输的效率。

由于word文件本身的复杂,使得各种图形信息提取的困难增大。为此,在设计时考虑采用与其本身结构类似的机制来设计提取模型,同时保持和原系统设计风格和实现上的一致。

三、技术细节

本方案中使用delphi访问word文件的方法:

word文件中每个图元都有一个唯一标识的名称和序号,分别是这样存取的:WordApplication.ActiveDocument.Shapes.Item(oleindex).Name;

Name属性返回一个图形元素的名称,其规则为:图形元素名称+该类图形的顺序数(例如:Line 1,Picture 2)。

WordApplication.ActiveDocument.Shapes.Item(oleindex).ZorderPosition;

ZorderPosition属性是按图形创建的次序排列产生,其值为整型。

其中WordApplicationword对象,可以为delphiservers组件,也可以用CreateOleObject()函数创建一个OleVariant对象。ActiveDocument是当前激活的文档,如果有多个激活文档,可以用Documents.Item(OleIndex)访问指定文档。Shapes对象为所有图形元素集合对象。包含了所有图形的属性和方法。访问图形集合中的单个元素需要调用其列表对象Item,它以数组的形式提供各种操作。

   每个图元的位置及大小由它的left,top,heighwidth值决定。由于word图形文件本身很复杂,涉及很多属性。为了简化这里列出其主要的属性信息便于提取。

图形属性:

 

图形(Shape)

序号

ZorderPosition

名称

Name

类型

Type_

大小

Height,Width

位置

Left,Top

调节器

Adjustments

走向

HorizontalFlip, VerticalFlip

旋转度

Rotation

画笔颜色

Line.ForeColor

填充前景颜色

Fill.ForeColor

文字环绕方式

WrapFormat

水平位置关系

RelativeHorizontalPosition

垂直位置关系

RelativeVerticalPosition

是否可见

Visible

 

以下所有图形都是从上面的图形对象(Shapes)继承而来,故以下提及的直线,任意多边形,图片,艺术字,文本框和组合图形都具有以上图形对象的属性。Type_HorizontalFlip, VerticalFlipForeColorWrapFormatRelativeHorizontalPositionRelativeVerticalPositionVisible。它们的取值都是office定义的以mso开头的常量类型(LongWord)。

Type_返回图形的类型(MsoShapeType),类型参数表及参数值如下:

参数名称

参数值(十六进制)

标识的图形

msoShapeTypeMixed

$FFFFFFFE

混合图形

msoAutoShape

$00000001

自动图形

msoCallout

$00000002

插图标号

msoChart

$00000003

图表

msoComment

$00000004

注释

msoFreeform

$00000005

任意多边形

msoGroup

$00000006

msoEmbeddedOLEObject

$00000007

嵌入式ole对象

msoFormControl

$00000008

窗体控件

msoLine

$00000009

直线

msoLinkedOLEObject

$0000000A

链接式ole对象

msoLinkedPicture

$0000000B

链接式图片

msoOLEControlObject

$0000000C

Ole控件对象

msoPicture

$0000000D

图片

msoPlaceholder

$0000000E

区域所有

msoTextEffect

$0000000F

艺术字

msoMedia

$00000010

多媒体

msoTextBox

$00000011

文本框

msoScriptAnchor

$00000012

脚本锚

msoTable

$00000013

表格

 

Height,Width,Top,Left等标识图形位置和大小的信息在word中采用精确的单精度类型,但是一般在delphi中的绘图都采用整数的象素值。所以这里提取图形位置和大小时采用银行家取整算法函数Round() 将浮点型值转换为整数型。另外在word中位置和大小的单位一般是按磅来计量的,将其转换成通用的象素值,需要采用如下转换:

象素值=要转换的值(单位为磅,该值是直接从word文件中提取的)×屏幕每英寸象素点数(一般为96/(每磅的毫米数(一般为2.835)×每英寸的毫米数(一般为25.4)

这样在delphi中就可以完全临摹出大小一样位置相同的Word图形来。分子分母同乘以10使得结果更加准确。

Adjustments图形调节器属性,用来调节诸如圆角四边形,艺术字效果等等,图形的调节器可以改变图形的外观风格。通过调节器的item列表属性访问调节器点的值,返回单精度型。

HorizontalFlip, VerticalFlip两个属性标识一个图形的走向。这两个属性的取值完全一样,其定义和参数和值如下:

type

  MsoTriState = TOleEnum;

const

  msoTrue = $FFFFFFFF;

  msoFalse = $00000000;

  msoCTrue = $00000001;

  msoTriStateToggle = $FFFFFFFD;

  msoTriStateMixed = $FFFFFFFE;

该属性对于正确提取直线有很重要的作用,比如一条自左上至右下,和自右下至左上的线就算位置和大小完全一样,但是可以通过HorizontalFlip, VerticalFlip属性知道他们的走向。

Rotation属性返回一个图形被旋转的角度。也是浮点型的。在word中图形显示的效果是直接旋转后的结果,但是如果用程序提取,只能提取该图形的初始位置,所以必须先提取图形的Rotation值然后通过程序中旋转处理才能正确的显示word中的效果。

ForeColor是前景色,有画笔前景色和填充前景色,分别存在LineFill对象下。颜色值是以整数形式存于ForeColorRGB属性下。

WrapFormat(文字环绕方式):这是个比较复杂的属性,它的环绕类型(WdWrapType)有如下几种:

  wdWrapSquare = $00000000;

  wdWrapTight = $00000001;

  wdWrapThrough = $00000002;

  wdWrapNone = $00000003;

  wdWrapTopBottom = $00000004;

环绕边框类型(Side)的参数如下:

wdWrapBoth = $00000000;

  wdWrapLeft = $00000001;

  wdWrapRight = $00000002;

  wdWrapLargest = $00000003;

图形环绕距离:DistanceTopDistanceLeft, DistanceBottom, DistanceRight四种,都是浮点型值。

环绕允许重叠属性AllowOverlap,类型为整数型,在VBA宏代码里一般用TrueFalse给它赋值。

RelativeHorizontalPositionRelativeVerticalPosition属性标识图形的位置参考对象,直接影响着图形的Left,Top值,RelativeHorizontalPosition属性是水平参考对象,分别有:页边距,页面,栏和字符四种,其参数值如下:

wdRelativeHorizontalPositionMargin = $00000000;

  wdRelativeHorizontalPositionPage = $00000001;

  wdRelativeHorizontalPositionColumn = $00000002;

  wdRelativeHorizontalPositionCharacter = $00000003;

RelativeVerticalPosition为垂直参考对象,分别有:页边距,页面,段落和行。参数及其取值如下:

wdRelativeVerticalPositionMargin = $00000000;

  wdRelativeVerticalPositionPage = $00000001;

  wdRelativeVerticalPositionParagraph = $00000002;

  wdRelativeVerticalPositionLine = $00000003;

Visible属性虽然表面上理解只是是否可见,但是其属性值却有多个:

msoTrue = $FFFFFFFF;

  msoFalse = $00000000;

  msoCTrue = $00000001;

  msoTriStateToggle = $FFFFFFFD;

  msoTriStateMixed = $FFFFFFFE;

自动图形:

自动图形(AutoShape)

名称

Name

风格

AutoShapeType

 

   自动图形的提取重点在于提取它的风格类型(AutoShapeType),在word中一共有138种风格类型。常见的有矩形,椭圆等等。

 

直线:

 

直线(Line)

名称

Name

 线宽

Weight

透明度

Transparency

虚实

DashStyle

风格

Style

前端形状

BeginArrowheadStyle

前端长度

BeginArrowheadLength

前端宽度

BeginArrowheadWidth

后端形状

EndArrowheadStyle

后端长度

EndArrowheadLength

后端宽度

EndArrowheadWidth

 

    提取直线信息时遇到的问题:

1,  直线的走向属性(HorizontalFlip, VerticalFlip)影响着一条直线是自左上到右下,自左下到右上,自右上到左下还是自右下到左上这几种斜线式的摆放,可以通过先提取他们走向的属性值确定该直线属于那种走向。

2,  直线的旋转,一条直线在word文件中显示的是它被旋转后的显示效果,但是如果直接读取坐标,位置和走向,最终显示的只能是这条直线的初始位置,它并不显示为旋转后的效果,所以必须取出其旋转角度(Rotation),然后处理旋转就可以正确显示了。其中关于旋转的数学公式如下:

顶点(x,y)围绕某点(x0,y0)旋转θ角度后到的另一点点坐标(X,Y)的计算公式:

X=xcos(θ)-ysin(θ)+x0(1-cos(θ))+y0sin(θ)

 =x0+(x-x0)cos(θ)-(y-y0)sin(θ);

Y=xsin(θ)+ycos(θ)+y0(1-cos(θ))-x0sin(θ)

=y0+(x-x0)sin(θ)+(y-y0)cos(θ);

 

艺术字:

 

艺术字(TextEffect)

名称

Name

 文本内容

Text

投影

Tracking

字体格式

Font

旋转字符

RotatedChars

边框图形

PresetShap

边框效果

PresetTextEffect

对齐方式

Alignment

格式化高度

NormalizedHeight

 

    word文件中很多图标识都是用艺术字来说明的,艺术字的提取相对简单,如上表所示,但是其中的信息包含较多,以上只列出了部分重要信息。要提取或者传输太多的信息显然是没有必要的,所以这里只提取部分重要的,可以确定一个艺术字的基本信息而不失大体效果的属性。

 

文本框:

 

文本框(TextFrame)

名称

Name

 文本内容

ContainingRange.Text

是否溢出

Overflowing

字体格式

Font

文本方向

Orientation

文本范围

TextRange

   

文本框信息的提取是比较简单的。它的形式只有两种,一种是文字横排,另一种是文字竖排。对于文字方向,可以从Orientation属性提取。提取文本框信息值得注意的一点是:有很多文本框的文字长度和宽度与框长度和宽度完全不一样。应该适当折中处理。其他信息可以忽略。

 

任意多边形:

 

任意多边形(Freeform)

名称

Name

顶点数

Length

分割类型

SegmentType

编辑类型

EditType

顶点

Points

 

任意多边形的信息除了位置大小等继承自shape的属性和方法外,主要的属性被封装在Nodes对象中,NodesLength是任意多边形的顶点个数,SegmentType是它的MsoSegmentType类型,一般参数有:msoSegmentLine = $00000000; msoSegmentCurve = $00000001; 两种。EditType属性是顶点的编辑类型,数据类型为msoEditType,参数包括:                  msoEditingAuto = $00000000;

  msoEditingCorner = $00000001;

  msoEditingSmooth = $00000002;

  msoEditingSymmetric = $00000003;

其中顶点(Points)的数据类型为OleVariantOleVariant类型本身就是一个复杂的复合型数据结构,可以存放多种数据。Points属性存储了顶点的坐标(XY),通过正常的servers组件是无法取得它的坐标的,因为作为任意类型的points属性无法赋值给一个正常定义的olevariant类型变量。所以这里只好采用了CreateOleObject方式获取。这地方是一个技术难点。设计期间几经周折才找到了方法。

 

图片:

 

图片(Picture)

名称

Name

亮度

Brightness

对比度

Contrast

透明色

TransparencyColor

颜色类型

ColorType

源文件名称

SourceName

 

    Word中可以嵌入很多类型的文件,包括图片音乐动画等等。此处使用的图片不是正常的粘贴嵌入,而是通过将一个外部图片(格式自由,一般是jpeg或者jpg)插入word文件,然后编辑该图片,另存为一个word副本文件,该文件只包含一个图片。将这个副本文件插入word文件形成的。所以提取这种类型的图片是比较困难的,图片文件本身被包含在word文件中。

如果以 "嵌入" 方式插入的话, 那就和源文件没有关系了, 也就没有了源文件的信息了; 这样就无法提取到插入图片的原始路径和名称信息了。如果是以 "插入为链接" 的方式的话, 实际上产生了一个 INCLUDETEXT , 这样就可以从 ActiveDocument.Fields(?).Code 中提取到源文件的名称以及路径。具体插入步骤如下:

"插入"――>"文件" 的对话框里, "插入" 按钮右边有个小的▼, 点一下, 在出现的下拉菜单里有 "插入链接" 字样的, 就是以 "链接" 方式插入的了. 这时, 在目标文件形成的实际是个 INCLUDETEXT , 要提取源文件信息的话, 可以通过枚举文档所得到的域, 判断是否为 INCLUDETEXT 类型。

不过, "嵌入" 方式是word中缺省的文件插入方式。所以必须采用word宏或者其他方式促使客户在插入图片文件时必须采用“插入链接”的方式插入。

组合图形:

 

组合图形(Group)

名称

Name

GroupItems

 

组合图形是将多个基本图元(包括组合图形)通过“组合”生成的图元。这样一来,对于那些由基本的图形组成的被看作整体且多次使用的图形将容易使用多了。一个组合可以包含另一个组合。组合之后的所有图元即是一个整体。访问组元素是通过GroupItems对象的列表Item访问的。组合图形的处理是比较繁琐而且复杂的部分,关于该部分的处理有如下两种方案:

第一种:

组合图形在重点单位作战部署图中主要出现以下情况。梯子(包括垂直放置和水平放置的两种),电梯,水源,救火点,方向定位图标。主要信息和处理方法如下:

  1,  梯子   

梯子包括垂直梯子和水平梯子。

梯子的主要图形元素组成为两条平行线中间包含9条等距线段. 中央一个矩形。

 绘制方法:

       规定梯子中,平行线和矩形的距离比,可以通过常规的办法绘制(逐一元素绘制)。

  2,  电梯

    电梯是一个带有两条对角线的矩形。

  绘制方法:

     根据获取的位置和大小可以用常规方法确定矩形的位置和大小,对角线的画法水到渠成。  

  3, 水源

    水源是由一个被一条垂直线段平分两半的椭圆(基本可以认为是圆),左边嵌入一个红色扇形(该扇形是一个有180个顶点的任意多边形)。

   其绘制方法:

     画圆,垂直中分线,一半红色扇形; 

  4, 救火点

     三条红色线段, 初始状态为,主线垂直,成一个正立树苗状.

   绘制方法:

      获得其旋转角度.和位置及大小.规定一个分差点和主线的比例。

  5, 方向定位图标

      这是最复杂的一个图标。包含一个艺术字,一个淡蓝色的椭圆,两条红色线段和一个填充色为红色的未闭合任意多边形。总共有4层组合。

      规定每个图形元素的位置比例。顺序按常规方法绘制。

 

四、实现的工程详述  

Office系列软件提供了功能强大的接口扩展编程vba,delphi提供的word2000.pas和office.pas单元封装了所有的接口控制word的属性和方法。使用十分方便,基本保持了和vb一样的功能。office软件的内部VBA对象关系,其中word对象中的众多对象如_document,Shape,Window都以一种自由的形式共享,可以部分层次的访问Application对象。

为了保持和整个系统设计思想的一致,维护的方便。这里运用oo的思想设计整个提取图形。将各种图形封装成简单的结构体,设计了一个PickUpWord类,封装了所有用到的图形结构体和提取的方法。

本系统中涉及的word文件基本用到的word图形有以下7种。

 

 

图形

type_

名称

生成方式

AutoShape

1

自动图形

包括矩形,椭圆等基本图形

Group

6

组合图形

组合各种基本图元而成

Picture

13

图片

插入保存成.doc格式的图片文件

WordArt

15

艺术字

由基本绘制操作生成

Line

9

直线

由基本绘制操作生成

Freeform

5

任意多边形

由基本绘制操作生成

Text Box

17

文本框

由基本绘制操作生成

         

五、总结

 

 

附件1  矢量图形的定义

 

一、  文件格式定义

1、        文件头格式

             vtr$20+FileLength(4bytes)+Vision(4bytes,0100)

             大小:[4+4+4] = 12

2、        文件内容分配及格式定义

自动图形部分文件格式

$FF01 +Length+AutoShapeType +Left+Top+Width+Height;

大小:[2+2+(1+2+2+2+2)] = 4 + 9 * n      (n为有多少自动图形,下同)

任意多边形格式

$FF05+Length+NodesLength+FillColor+Color+Weight +ArrayPoints;

大小:[2+2+(2+1+1+1+(4))] = 4 + 5 * n + m * 4    

n为有多少任意多边形,m为所有的任意多边形所有顶点和)

        组合图形格式:

$FF06 + Length + Style + Left + Top + Height + Width;

大小: [2 + 2 + (1 + 2 + 2 + 2 + 2)] = 4 + 9 * n

(n 为有多少组合图形. Style 标识图形的风格及特殊参数(其值大于10的包含旋转角度))

线段部分文件格式

a, 无末端风格的线段:

$FF09+Length+x1+y1+x2+y2;

大小:[2+2+(2+2+2+2)]=4+8*n    

n 为有多少线段)(颜色默认为黑色,线段宽度默认为1,无末端风格)

b,有末端风格的线段:

$FF99+Length+x1+y1+x2+y2+Weight+Color;

大小:[2+2+(2+2+2+2+1+1)]=4+10*n     n 为有多少线段)

图片部分文件格式

$FF0D+ Length+TextLength+Direction+SourceNameLength+SourceName+ Left+Top+Height+Width;

大小:[2+2+1+?+ (1+??+2+2+2+2)] =5+(9+??)*n+?        n 为有多少图片,?为所有图片的路径长度,??为图片源文件名的长度)

     文本框部分文件格式

$FF11+Length+TextLength+Text+Orientation+FontSize+Left+Top+Width+Height;

大小:[2+2+(1+?+1+2+2+2+2+1)] = 4+(11+?)*n  n 为有多少文本框,?为每个文本框包含的字符长度)

艺术字部分文件格式

$FF0F+Length+TxetLength+Text + left+Top+Width+Height+FontSize;

大小:[2+2+(1+?+2+2+2+2+1)] = 4+(10+?)*n      n 为有多少艺术字,?为每个艺术字包含的字符长度)

文字部分文件格式

$FF03+Length+Text;

大小:[2+2+?]=4+                    (?为文字部分的长度)           

3、        文件尾部分文件格式:

$FFFF;

大小:[2] = 2

 

注解:

vtr            文件扩展名称

$             为十六进制数前缀(Delphi)

FFXX         图形类型标识

FileLength      文件长度。

Vision         版本信息。

Length         一组图形的字节数。

AutoShapeType 自动图形类别。

Direction       文件全路径名。

Orientation     图形走向。

Length         字符的长度

Left           图形距左边框距离

Top           图形距顶部的距离

Width         图形宽度

Height         图形高度

Weight        图形的线宽

NodesLength   图形顶点字节数

X1,y1,x2,y2    一条线的两个端点坐标

ArrayPoints    顶点坐标(x ,y

FontSize      字体大小

Color         画笔颜色

FillColor      填充颜色

Rotation       图形的旋转度

EndHeadStyle     图形末端风格

SourceNameLength 图片源文件名长度

SourceName      图片源文件名

Text          文本信息

TextLength     文本长度

?             标识动态确定长度(文本或者字符)。

标注:带有红、绿色波浪下划线部分数据格式相同,累加每个图形的数据。

根据测试,按上述提取图形得出文件容量为:4,968字节。(测试文件为:《标准层房间作战力量布置图》

 

 

附件2  通讯协议

 

posted @ 2005-03-18 10:26  JustLive  阅读(1863)  评论(0编辑  收藏  举报