如何减小带有嵌入式图片的RTF文件大小?

16

我们有一些代码,可以从RTF模板生成RTF文档。它基本上是在RTF文件中搜索和替换特殊标记。通过网页可以访问此功能。

通常情况下,处理时间非常快。

然而,我们需要在模板中嵌入一个图像。我们一直在使用Word的“插入/图片/来自文件…”功能将其嵌入为JPEG图像。但我们发现所得到的RTF文件大小极大地依赖于图像。

例如,我插入了一个20k的JPEG徽标(基本上是一个纯色背景和一些文本),RTF文件的大小从约390k(没有图像)增加到510k(带图像)。

然后我们插入了一个包含屏幕截图的JPEG,即图像包含文本、多种颜色等。这个JPEG文件大约有150k。使用这个图像,RTF文件的大小从390k增加到3.5MB。

因此,Word用于将图像存储到RTF中的编码不是线性的。我猜测它取决于JPEG图像中的内容。

我需要保持RTF模板的大小最小,以尽量减少文件处理时间。

  • 有人有什么想法来最小化嵌入图像的RTF文件大小吗?
  • 有没有办法控制Word使用的编码?我找不到任何选项。
  • 有人知道Word/RTF使用的二进制编码类型是什么吗?

先谢谢您。


2
我并没有答案,但几乎可以确定的是,这是因为它被嵌入为未压缩位图,而不是像JPEG这样的压缩表示形式。 - Sean Owen
6个回答

17

这是最佳解决方案

http://support.microsoft.com/kb/224663

摘录:

症状

当您将包含 EMF、PNG、GIF 或 JPEG 图形的 Microsoft Word 文档另存为其他文件格式(例如,Word 6.0/95 (.doc) 或 RTF (.rtf))时,文档的文件大小可能会显著增加。

例如,一个包含 JPEG 图形的 Microsoft Word 2000 文档如果保存为 Word 2000 文档,则其文件大小可能为 45,568 字节 (44.5KB)。但是,如果将该文件另存为 Word 6.0/95 (.doc) 或 RTF (.rtf),则文件大小可能增长到1,289,728 字节 (1.22MB)。

原因

这是 Microsoft Word 中的设计功能。如果将 EMF、PNG、GIF 或 JPEG 图形插入到 Word 文档中,则在保存文档时会保存两份图形的副本。图形以适用的 EMF、PNG、GIF 或 JPEG 格式保存,并同时转换为 WMF (Windows 图元文件) 格式。

解决方案

警告:如果对注册表编辑器的使用不当,可能会导致严重的问题,需要重新安装操作系统。Microsoft 无法保证您可以解决由于不正确使用注册表编辑器而导致的问题。请自行承担使用注册表编辑器的风险。

要防止 Word 在文档中保存两份图形副本,并缩小文档的文件大小,请在 Microsoft Windows 注册表中添加 ExportPictureWithMetafile=0 字符串值。


链接页面介绍了Word如何保存图像的两个副本(原始文件和未压缩版本),并提供了一个注册表更改,告诉它仅保存原始文件。非常有趣。 - codeulike
我认为这个答案比标记为答案的那个更好。 - bfhd
我不确定是否有人知道如何在WordPad中实现相同的功能?我尝试将“ExportPictureWithMetafile=0”字符串值添加到“HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Wordpad\Options”,但似乎没有任何效果。 - ulatekh
WordPad现在似乎会在Windows 10中为我压缩图像。对于任何阅读此内容的人,请尝试在WordPad中打开文件并在编辑注册表之前保存。它可能会为您压缩文件。 - Tronald

5
在RTF文件中,图像以未压缩的WMF格式存储。在Mac上,则为macpict格式。为了保持文件大小,最好将图像链接到文档中,而不是将副本插入文档。这样做的代价是必须将文件放在一起。
编辑: 是否可以压缩RTF文件?使用zip/rar可以减小文件大小,但首先需要解压缩。据说有一些工具可以进行rtf压缩,但我从未使用过。

谢谢。压缩文件并没有帮助——我仍然需要解压缩才能处理文件。我的问题不在于文件存储大小,而是处理RTF所需的时间。我不太理解链接方面的知识——可能是我在Word技能方面欠缺……是否有可能让Word超链接到一个URL,并在文档中显示该URL的内容?我可以通过URL轻松地使我的图像可用。只要图像出现在读者的文档中,且读者无需进行任何操作即可获得图像,那么我就很满意(即我不希望用户必须单击链接)。 - A_M
添加超链接很容易,可以在Word本身或VBA中完成,但抱歉我不知道如何使图像在rtf文档内可见,但不包含WMF的副本。例如,如果您有非白色背景,则屏幕截图往往比它们需要的大得多。您可以考虑编辑图像并将它们保存为bmp文件。BMP格式将为您提供WMF的大小。将其保存为16位图像时会失去多少颜色信息? - DaveParillo
抱歉 - 我的意思是16色图像。我刚刚保存了我的显示器转储 - 原本是24位3.5M图像。保存为16色,大小为641K。图像确实有些损坏,但仍然“可用”。 - DaveParillo

1

首先要记住的是,每个字节都使用2个字符(两个字节)存储,这意味着增量至少是原始图片的两倍大小。

其他需要注意的是,Word和Word Pad插入相同图像的不同(风格或格式)以及其他字段(RTF可以在没有它们的情况下显示)。

以下是用于在RTF中插入图像的一些脚本(https://joseluisbz.wordpress.com/2011/06/22/script-de-clases-rtf-para-jsp-y-php/),以及一个使用示例(https://joseluisbz.wordpress.com/2011/07/16/subiendo-imagenes-png-y-jpg-y-archivos-a-mysql-con-php-y-jsp-y-mostrarlos-en-rtf-usando-clases/

现在,您可能需要用另一张图片替换原始图片(http://joseluisbz.wordpress.com/2013/07/26/exploring-a-wmf-file-0x000900/)。


1

我们在工作中做过类似的项目。只是我们没有使用“插入/图片/来自文件…”功能。我们的模板有一个名为[photos]的标签,我想你的也是这样。当我们处理文档时,我们用显示图像所需的RTF代码替换标签。我们将它们放在表格中,每行显示两个图像,顶部还有一行标题。

因此,您可以在模板中放置一个标签[photos]。然后用RTF代码替换标签。您可以在网上找到一些关于这些代码的好参考资料。例如:here

现在,我的代码看起来像这样:

\par {\rtf1\ansi\deff0{\trowd\cellx8810 {标题}\intbl\qc\cell\row}{\trowd\cellx4405\cellx8810{\pict\jpegblip\picwgoal4000\pichgoal3000\piccropl-50\piccropr-50\piccropt-50\piccropb-50\hex 将图像转换为十六进制字节数组 }\intbl\cell{\pict\jpegblip\picwgoal4000\pichgoal3000\piccropl-50\piccropr-50\piccropt-50\piccropb-50\hex 另一个图像 }\intbl\cell\row}

如果您将图像转换为字节数组,可以使用BitConverter.ToString(array)获取十六进制代码。只需将破折号“-”替换为“”即可。

我们的文件所占空间不到“正常”RTF的十分之一。如果我们使用像Notepad++这样的编辑器打开文档代码,我们可以看到RTF代码,但是如果我们将文档打开并另存为RTF(更改名称),它将从1.5Mb增加到50Mb! 我猜DaveParillo的回复可以证明这一点:我只写了每个图像一次。

希望有所帮助。 干杯,伙计


0

Swartbees的答案对我非常有效。我首先使用G.I.M.P.将图像质量降低到“0”,然后保存为jpeg格式。在按照Swartbees上面建议的Microsoft解决方案后,我重新将图片插入文件中,大小增加微不足道,从229k到279k(而不是29000kb)。

感谢你们的建议。


-1

是的,通过删除冗余字符来实现。为了做到这一点,您必须将它们重新插入到流中。

例如,如果您在一行中有超过二十个f字符,则可以在流中替换为f[20]。这是一个开始。

-祝你好运。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接