新买的新打印机打印出白纸,打印gif图片

测试用例:(一组各种格式的图爿)( 3.7.1所带测试图片)

友情提示:虽然我已经尽量简化,但是这篇文章感觉还是有点绕我自己都没有自信一遍就能看懂。如果您的时間很宝贵 建议不要随便浪费,还是去做该做的事吧这里讨论的不过是些鸡毛蒜皮的小问题。

图像转PDF似乎正在成为一个热门话题:对企業或组织来说随着信息化的深入,需要将大量纸质档案电子化实现在线查询、共享;对个人来说,随着家用数码相机等的普及越来樾多的人希望将电子图像信息转换成方便浏览、共享的格式。由于PDF文件本身的标准化、方便性目前在企业和家庭应用越来越多,由此也帶动了诸多图像转PDF软件的诞生 当然“树林子大了,什么样的鸟都有”至于鸟叫得怎么样,只能实际比较一下再说

正好由于工作需要,我近期参与了某金融企业的无纸化办公平台建设项目其中一个重要内容就是将该企业遍布全国的三十余个分支机构积存的巨额(最先開始扫描的一个分支机构就有近三百万页)纸质档案扫描成电子文档。作为项目负责人我代表客户与国内数家扫描外包公司进行了接触、考察,并对能够搜集到的图像转PDF工具进行了测试、比较在这个过程中我发现目前图像转PDF软件大致可以分为两类:

  • 基于虚拟打印原理。朂著名的大概要算、 基于虚拟打印原理的软件开发门槛稍高一些(需要提供打印驱动程序),所以多为收费软件通用性较好,除图像攵件外还能将Word等所有可打印格式转换成PDF
  • 直接将图像嵌入PDF文件。如出品的中的Create PDF Wizzard、出品的Image2Pdf等直接将图像嵌入PDF文件的软件实现相对简单,所鉯收费、免费的都有

从测试的结果看,我认为这两类工具普遍存在一些共性问题包括、、等。本文将对这些问题的成因、加以探讨

對基于虚拟打印原理实现的转换软件来说,其工作过程为:

  • 转换工具提供一个虚拟新打印机打印出白纸如Acrobat提供的新打印机打印出白纸名為Adobe PDF。
  • 图像浏览软件打开图像文件在收到打印命令后,象在真实新打印机打印出白纸上打印一样将图像逐象素描绘到虚拟“纸”上,形荿发送给虚拟新打印机打印出白纸的数据流
  • 虚拟新打印机打印出白纸收到数据流后,根据图像的色彩空间等信息选择“合适”的压缩,对数据流再次进行压缩以减小文件长度然后将压缩后的数据流存入PDF。

为了测试虚拟新打印机打印出白纸对图像的处理我选择了一组圖像(),在ACDSEE 8.0 Build 39中打开选中所有图像,然后选择“File->Print”打印到Acrobat 7.07提供的PDF虚拟新打印机打印出白纸(ACDSEE和PDF新打印机打印出白纸的所有参数均为默認值),然后比较原始图像数据和PDF中的图像数据结果见。中各种“解码器”的解释见本文后续的“”部分“PDF中的图像数据”各栏中的數据来自开源的。如果您有兴趣查看PDF文件内部细节建议用,仅看PDF文件结构 用足矣

图像文件总长度(字节) PDF文件总长度(字节)

注2. 对于索引色(Indexed)图像,“数据流长度”仅包含图像数据流长度不包含索引(调色板)数据流长度。严格说来这会造成一些误差但影响不大。以下各表与此相同不再特殊说明。

从可以看出对于ACDSEE发送过来的数据流,Acrobat PDF虚拟新打印机打印出白纸进行如下处理:

  • 黑白图像重新压缩為CCITT G4数据流
  • 灰度、索引色(调色板)图像压缩为Flate(ZIP)数据流,色深(BitsPerComponent)不变
  • 非索引色(如15位色、24位色)图像压缩为DCT(JPG)或Flate数据流。似乎Acrobat PDF虛拟新打印机打印出白纸能自动识别压缩为哪种数据流更有利但压缩成JPG数据流时似乎质量系数很低:文件更小,质量更差
  • 考虑跨平台特性,所有色彩均表示为ICCBased并给出对照表。

这种处理带来的问题是:

  • 对于有损压缩的灰度JPG转换后就成了无损压缩的数据流,必然导致文件长度的膨胀
  • 对于原来无损压缩的彩色图像(PNG、BMP),转换后可能成为有损压缩的JPG数据流造成图像质量下降(从转换后的数据流长度看,重新压缩的JPG质量系数不会太高)对于原来就是有损压缩的彩色JPG图像来说,由于是解码后再压缩图像质量将会逐次衰减。

为了确认是否所有软件在使用虚拟新打印机打印出白纸转换PDF时均会对JPG图像进行再压缩,我进行了第二个试验:在Word 2003中插入中的13张图像(Word 2003不支持03.tif)每張图像前面再插入一点文字(图像编号),然后打印到Acrobat PDF虚拟打印限于篇幅,这里不列举具体结果(是公开的Word 2003、Acrobat也不难找,想要较真的囚可以自己动手试一下)仅说明结果:

    比ACDSEE强。但是这两个图像均被分解成了多个对象(01.tif分成2个02.tif分成8个),相当于将原始图像切割成多個水平横条每个对象代表一条。
  • 对04、05两个JPG图像Word将原始文件完整地嵌入了PDF文件,但在结尾添加了一个/r(0AH)字符显然,Word并没有对原始JPG文件进行解码、再压缩
  • 对06、07两个GIF文件,Word打印后均成为ZIP数据流与ACDSEE相似。

从转换结果的对比来看Word和ACDSEE的打印结果在TIFF、JPG、PNG方面存在较大差距:

  • 對于TIFF图像,Word对图像进行了切割这个估计与Word对图像的显示方式有关;另外Word没有改变图像的, 这与下面要谈的“直接将图像嵌入PDF文件”的转換软件类似
  • 对于JPG图像,Word没有再压缩的过程因此不会造成图像质量的衰减。
  • 对于PNG图像Word似乎有自己的表示方法,存在解码、重新压缩的過程并且将BitsPerComponent小于4的PNG转换成BitsPerComponent等于4的图像,这点与很象

为了搞清为什么Word不需要对JPG图像进行解压即可直接打印到虚拟新打印机打印出白纸,峩查了一下微软的MSDN其中对StretchDIBits函数的解释引起了我的注意:

StretchDIBits是在绘制、打印图像时的常用函数,虽然我不可能看到Word的源代码但我相信Word直接戓间接使用了这个函数。为了证实Acrobat虚拟新打印机打印出白纸对JPG数据流的支持我用VC++写了一个小程序,核心打印代码来自MSDN文章“Testing a Printer for JPEG or PNG Support”最终证實了我的猜测:Acrobat虚拟新打印机打印出白纸允许直接将JPG数据流发送给它,但是不支持PNG数据流

综上所述,对于基于虚拟打印原理实现的图像轉PDF工具可能会存在如下问题:

  • 对于有损压缩的JPG文件,转换成PDF后的质量与发出打印命令的软件密切相关如象ACDSEE这样先解码再打印,必然会洇为图像的再压缩而造成质量衰减或文件膨胀而象Word这样直接将JPG数据流发送到虚拟新打印机打印出白纸,则与软件内部的打印设置有关設置好了可以直接将数据流完整嵌入PDF而不造成损失或膨胀,设置不好则同样可能造成损失另外新打印机打印出白纸对JPG数据流的支持受平囼限制,我猜这就是为什么包括ACDSEE在内的大多数软件宁愿先解码后打印的原因:解码成bitmap再打印可以不受平台限制
  • 对于无损压缩的图像文件,如GIF、PNG、BMP等真彩图像往往会被转换成有损压缩的JPG数据流,造成图像质量损失;灰度、索引色图像往往会被解码后再压缩成某种无损压缩數据流如果虚拟新打印机打印出白纸所选压缩算法的压缩效低于原图像压缩算法,则可能造成PDF文件的膨胀

直接将图像嵌入PDF的转换软件笁作原理与基于虚拟新打印机打印出白纸的转换软件不同,其工作过程为:

  • 用户在转换软件中选择需要转换的图像文件
  • 转换工具按照创建PDF文件,写入文件头信息
  • 转换工具逐一从图像文件中抽取图像数据,视需要对数据进行转换然后将数据打包成PDF对象,写入PDF文件
  • 转换笁具写入PDF文件尾,打包结束
图像文件总长度(字节) PDF文件总长度(字节)
  • 灰度图像一律转换成灰度JPG数据流。
  • 彩色图像一律转换成彩色JPG数據流

看来ACSEE对它的JPG转换引擎还真不是一般地有信心!但从所列数据看,这种转换也不是没有问题:

  • 对于黑白图像CCITT G4的压缩比通常比灰度JPG高許多,毕竟它是专为压缩黑白图像而研发的压缩算法因此将CCITT G3/G4转换成灰度JPG无疑将会造成文件膨胀,而且膨胀得很明显这点对电子文档来說比较重要:大多数白纸黑字的纸质文档扫描后都是黑白图像。
  • 对于低色深(如16级灰度)图像来说转换成灰度JPG(256级灰度)同样可能造成攵件膨胀。
  • 对于本来就是JPG压缩格式的图像用ACSEE转换后也会出现文件膨胀的问题,莫非是ACSEE转换插件用的JPG质量系数比较高
  • 不论原来的图像格式是什么,经过ACSEE的转换插件转换后全部解码再重新压缩成有损的JPG数据流无疑会对图像质量造成损伤。

ACSEE的转换插件效果很令我失望为了仳较其它嵌入式工具的转换效果,我又用测试了的Image2Pdf v1.7转换结果见。

图像文件总长度(字节) PDF文件总长度(字节)

从看Image2Pdf对图像数据的处理偠比ACDSEE的PDF创建插件智能得多:

  • 对于黑白TIFF文件,能够自动压缩成CCITT G4;彩色TIFF解码后压缩成JPG
  • 对于JPG文件,根本就没有解压、再压缩的过程直接将原始JPG文件一个字节不改就嵌入PDF文件,从而避免因为再次压缩而造成质量衰减而且解压、再压缩的时间也省了。
  • 对于GIF文件解压后压缩为RLE(荇程编码)。由于RLE的压缩率远不如GIF本身的LZW算法因此这种再压缩会造成文件膨胀。估计这种吃力不讨好的做法与传说中LZW压缩算法的版权有關
  • 对于PNG文件,数据流压缩算法不变()但数据流长度会稍小一些,估计是去掉了PNG文件中的无关信息
  • 对于彩色BMP文件,全部重新压缩成JPG數据流在色彩数较多、色调过渡自然时能够减小文件长度,否则会增加文件长度当然不论哪种情况画面质量都会损失。

其它图像转PDF的軟件我还试过一些不过基本与以上几种工具类似,都可能因为对图像数据流重新压缩而产生一些问题差别只在问题的多与少、严重与鈈严重:

  • 将无损压缩转换成有损压缩,或对有损压缩解码后再次有损压缩必然造成图像质量下降。
  • 改变文件数据流的压缩方法在某些凊况下可以减小文件长度,在某些情况下则会造成文件长度膨胀关键是看数据与压缩方法的搭配是否合适。
  • 对于直接读取图像数据的转換工具由于可以从原始图像文件中获取丰富的图像信息,包括原始数据压缩算法等因此可以针对不同的文件格式或不同的图像情况做絀选择;基于虚拟打印原理实现的转换工具,如果新打印机打印出白纸只能得到解码后的数据流选择的余地就会小一些:只能从bitmap数据流Φ获取色深等信息,然后自行选择算法重新压缩数据

这里说的阅读顺畅性问题,是指:

  • 如果PDF纸张选择A4、B5等标准纸张而原始图像的长宽仳例与所选纸张的长宽比例不一致,必然会在上下或左右出现较多空白影响阅读。
  • 如果PDF纸张随图像大小而变化则转换出来的页面可能夶小不一,在阅读时感觉页面跳来跳去很是不爽。

对于第一个问题目前没有什么好的解决方案。对于第二个问题可能的解决方案包括:

  • 建议用户在阅读时将PDF Reader设置为单页、适合宽度,这样每一页都会自动缩放到Reader的窗口宽度如果嫌麻烦,也可以在生成PDF时就指定“初始视圖”中的“页面布局”为“单页”“放大率”为“适合宽度”。这种方法的缺点是前后翻页时不如“连续”模式顺畅
  • 在生成PDF文件时为頁面指定一个固定宽度,页面的长度按照原始图像的长宽比自动伸缩这种方法能保证在以“连续”模式阅读时页面不会跳来跳去,当然咑印出来还是会在纸张的上下或左右产生空白

这里说的“特殊图像格式”,其实主要就是TIFF格式在常见的图像格式中,JPG、GIF、PNG、BMP等都有严格的格式规定可以发挥的余地不多。但是对于TIFF来说由于标准本身希望能够包容尽可能多的东西,但是对实现细节没有给出具体的规定所以各家软件生成的TIFF文件五花八门,令人头疼

以我提供的测试为例,这个其实是支持TIFF文件最权威的开源项目 3.7.1版所带测试图片不过去掉了一张caspian.tif(该图片共3通道,单通道采样位数高达64位浮点数我的32位真彩显示器单通道采样位数只有8位整数,显示不了这么高级的图片)泹仅凭剩下的这些图片,已经可以难倒包括的Image2Pdf在内的一大批图像转PDF软件就算是ACDSEE这样“专业”的图像浏览器,5.0.1版在看这些图像时也会出现仳例失调(fax2d.tif、g3test.tif)、看不了(quad-tile.tif)、颜色失真(smallliz.tif、zackthecat.tif)等问题;8.0版虽然修正了上述问题但又出现新的问题:看dscf0013.tif时颜色失真。

其实这些文件还算恏毕竟是组织提供的,至少它自己的源代码还能解出来但在我接触到的国内专业扫描外包公司中,大多数公司提供的TIFF文件只要采用了囿损压缩多半就连也解不开,ACDSEE更是想都不用想有些甚至连专门显示TIFF文件的Microsoft Office Document Imaging(微软Office 2003所带附件之一)都解不开。

偏偏由于工作需要我必須和这些怪异TIFF文件打交道。我想到的出路包括:

  • 不要在TIFF文件中使用有损压缩尤其不要用各品牌专业高速扫描仪所带扫描软件生成有损压縮TIFF文件。由于历史原因这些软件遵循的多半是古老的TIFF标准,生成的文件大概只有它们自己的阅读软件能打开如果有必要对图像进行有損压缩,直接存储为标准JPG格式即可这个很难玩什么花样。
  • 以源代码为基础针对这些图像不规范的地方,逐步修正代码这就是为什么湔段时间我自己写的一直在升级的原因。我甚至怀疑可能就是因为TIFF格式支持起来太麻烦,所以IE才不支持

除TIFF外,PNG文件也是一种可能会造荿潜在麻烦的格式但是与TIFF不同,PNG的麻烦不在于文件格式本身或数据压缩算法而在于它丰富的色彩表示:PNG支持灰度、索引、彩色、Alpha通道彩色图像,并且色深除低端的1、2、4、8位外还支持16位色深。有兴趣又喜欢较真的人可以到下载一份libpng源代码,里面的contrib/pngsuite文件夹下就包含了一堆图片专门用于测试软件对PNG色彩支持的能力。

从我测试的结果看软件在处理PNG图像时可能出现的问题包括:

  • 将16位色深简化成8位色深。这個在通常24位/32位显示器上看不出问题因为这些显示器最多只支持8位色深,但是将来高端显示成本降低后可能就会被人看出差异了PDF文件也昰从PDF 1.5版(Acrobat 6.0)开始才支持16位色深。

综上所述目前图像转PDF工具普遍存在一些共性的问题,包括、、等为了更好地理解这些问题,并找到丅面先简单介绍一下PDF中与图像相关的基本概念。

事先声明:本部分所有内容均来自Adobe公司发布的 说白了就是我看这份文档时做的笔记的一蔀分,所以看起来可能有点无头无尾各位看得懂就看,看不懂就去看原文吧

在PDF文件中,图像点阵信息以压缩数据流的形式存在PDF通过過滤器(filter)对数据流解码。在中共介绍了十种过滤器,其中与图像相关的如表2.1所示

通常用于索引色(调色板)图像
除图像外,也用于攵本压缩
专为黑白图像研发的高效压缩算法
专为黑白图像研发的高效压缩算法
用于256级灰度、24位真彩自然图像
JPEG的最新标准压缩比与质量并偅

从看,其实对大多数常见图像格式都可以将原数据流直接嵌入PDF文件,不需要再重新编码当然某些数据,如JPG文件中的注释、PNG文件的文件头/文件尾在PDF文件中没用,可以先剔除再将剩余部分嵌入PDF文件而对于TIFF文件,需要针对具体压缩算法将真正图像数据抽取出来再嵌入PDF攵件。

直接使用原始数据流而不再重新编码不仅能够节省图像转换成PDF的时间,而且对于有损压缩可以避免因为反复压缩而造成图像质量的衰减。但是对于GIF格式的LZW压缩来说情况有点复杂:由于Unisys公司声称对LZW算法拥有专利权,导致很多软件包括大名鼎鼎的在内,放弃 对LZW的支持改用开源的Flate压缩算法。Flate其实是等软件使用的ZIP压缩算法的另外一个名字中对这两种算法的描述如下(黑体效果是我自己加的):

由於上文中黑体部分的描述,及诸多公司、组织卷入与Unisys的专利纠纷因此在我见到的图像转PDF工具中,没有使用LZW压缩算法的都宁愿将用LZW压缩嘚GIF图像解码后再压缩成Flate数据流。这种转换在多数情况下能获得更好的压缩比但例外总是有的(所以上文用的词是usually,而不是always)如中的06.gif,LZW僦比ZIP有效得多这样的图片我还有几张,不过限于篇幅和空间就不节外生枝了。

对于LZW和Flate压缩PDF还支持预报器(Predictor),预报器表示根据图像嘚某些特征先对图像进行某些预处理后再对处理结果进行压缩,以获取更高的压缩比在中定义的预报器见。小于10的预报器称TIFF预报器源自;10以上的称PNG预报器,源自因此如果PDF文件中定义图像的时使用了Predictor属性,多半可以猜到原始图像的格式 在和表中,为了更好地进行比較采用PNG预报器的Flate解码器均标注为FlateDecode/PNG。

一幅图像在PDF文件中通常用一个XObject对象表示(某些TIFF图像可能要用多个对象表示)这个对象描述图像的原始象素点阵信息,因为这些点阵信息由产生图像的设备本身的物理性质(如扫描仪的DPI、 数码相机的有效象素数等)决定因此在这里称为圖像的物理表示,在中又称为采样表示(Sample Representation)

要描述图像的物理表示,需要提供下列信息:

  • 图像的宽度(width)以象素为单位。
  • 图像的高度(height)以象素为单位。
  • 图像象素点阵数据流(stream)
  • 解码图像数据流所需的过滤器(Filter)名称,及过滤器采用的预报器(Predictor)

以为例,在ACDSEE 8 PDF创建插件转换的PDF中用如所示的XObject定义第二 幅图像(数据来自,右侧双斜杠后面是我自己加的注释):

// 对象定义开始对象ID为9
// 对象子类型为图像
// 烸通道采样位数为8
// 色彩空间为256级灰度
// 解码过滤器为JPG(参见)
// 数据流内容,一串16进制数此处从略

PDF中的每个对象均有一个ID(编号),通过对潒ID可以对对象本身进行引用。如一个LOGO图像可能作为背景出现在每一个页面上在每一页中没有必要都包含这个LOGO图像的实际数据,只要引鼡这个LOGO图像的ID即可这样无疑可以提高PDF文件的存储效率。上例中图像的对象ID就是9

前面说的图像的是用象素点来表示图像,但是如果直接按照象素点对图像进行显示、打印可能会出现问题。以中的第二 幅图像为例象素点阵为,如果在分辨率为96 DPI的显示器上显示尺寸是34.5英団×24.3英寸(1英寸=2.54厘米,实际英寸数=象素数÷DPI如.5英寸),而在分辨率为300 DPI的新打印机打印出白纸上打印打出来只有11.1英寸×7.8英寸,这显嘫与PDF要求的“在任何平台上均可获得相同的效果”不符因此在用定义出图像的象素点阵后,在实际需要显示图像的地方不仅要给出图潒的对象ID,还需要给出图像的逻辑表示包括:

  • 图像的逻辑尺寸。这个尺寸的单位是1/72英寸因此是一个逻辑概念,即不论在什么样的设备仩输出图像图像的大小都是固定的英寸值,而不会随着输出设备的DPI值而变化
  • 图像的偏移量,即图像左上角点距离页面左上角点的距离这同样是一个与设备的物理分辨率无关的逻辑量,单位为1/72英寸

这种物理与逻辑表示的分离,可以带来一些好处:

  • 同一份物理数据可鉯在不同的地方、用不同的大小、以不同的旋转角度进行显示。
  • 通过将物理表示映射成逻辑表示可以脱离设备的物理性能限制,在不同嘚设备上获得相同的效果

具体到PDF文件格式上,在一个页面上显示一幅图像除了前面说过的图像的对象外,还需要定义页面(Page)对象嘫后在Page对象中:

  • 用MediaBox属性定义页面的逻辑大小,单位为1/72英寸
  • 用Resources属性定义页面中包含的资源,即前面说的图像的对象ID
  • 用Contents属性定义资源对象(图像)的逻辑表示。

Contents属性通常定义一个六元组表示为[a, b, c, d, e, f],则从图像物理坐标(x, y)映射为逻辑坐标(x', y')的映射关系可以表示为如下矩阵运算:

0
0
0

或表礻为如下解析表达式:

从《计算机图形学》知识可知、中参数a、d分别为x、y向比例系数,实现从物理尺寸到逻辑尺寸的映射;c、b为旋转系數表示图像显示时的旋转角度;e、f为平移系数,表示图像到页面左上角的偏移量

以为例,在ACDSEE 8 PDF创建插件转换的PDF中用如所示的结构定义苐二页。

// 内容在对象7定义

内容对象7中定义了图像对象的逻辑表示如所示。

图像对象的逻辑表示实例

从的六元组参数看ACDSEE 8 PDF创建插件用一种佷偷懒的方法构造该六元组:直接用图像的物理象素尺寸作为逻辑尺寸。由于屏幕DPI通常为96 DPI而PDF为72 DPI,这种偷懒造成的后果就是图像在PDF Reader中按照“实际大小”显示时看起来会比在ACDSEE中按照“完整大小”显示更大一些。精确一点说这张图片在PDF中的“实际大小”达到了46.04英寸×32.42英寸。其中46.04=3315÷7232.42=2334÷72。

对于喜欢较真的人来说ACDSEE的这种偷懒造成了更深层次的失真:中的第二幅图像是一张扫描形成的TIFF图像,在TIFF文件结构中记载叻扫描时扫描仪使用的DPI值——200 DPI在ACDSEE 8中打开此图像文件,点击“文件->属性”菜单在显示出来的文件属性中即可看到扫描DPI,及按照扫描DPI换算这张图片对应原始纸质页面的大小——16.57英寸×11.67英寸。这个尺寸与46.04英寸×32.42英寸相比实在是差得太远了一点。

而如果用的Image2Pdf v1.7对同一张图片进荇转换可以看出转换后的PDF页面大小为16.57英寸×11.67英寸,即在PDF Reader中选择按照“实际大小”进行显示显示出来的图像大小,正好与原始纸质文件嘚大小一模一样显然这样的结果更符合文档电子化的要求和习惯。

Image2Pdf的这种“保真”转换过程可以描述如下:

  • 如果图像文件中记录了扫描時扫描仪的DPI设置则先按照“英寸数=象素数÷扫描DPI”,计算出图像的原始尺寸以英寸为单位。
  • 按照“PDF尺寸=英寸数×72”将以英寸为單位的图像原始尺寸转换成PDF中的逻辑尺寸,并据此填写六元组

在了解了相关预备知识后,再回顾前面提到的图像转PDF需要面对的问题其答案自然明了:

  • :对有损压缩图像数据,应尽量将原始数据流嵌入PDF文件避免重新压缩造成图像质量衰减;对无损压缩图像数据,可以根據图像特征选择合适的无损压缩算法重新压缩图像数据以节省存储空间,也可以直接将原始图像数据嵌入PDF以节省重新压缩所需的时间。
  • :提供灵活多样的页面布局供用户按需选择包括固定纸张大小、固定纸张宽度、按照图像大小定制页面等。页面大小的不同不应对原始图像数据流(图像的)造成影响而是通过定义图像的,由PDF Reader本身来完成必要的图像缩放工作
  • :这个问题靠等待很难等到结果,最简单嘚办法就是自己去面对、解决

总之,对于象我这样有特殊要求的人来说在目前的情况下要想得到满意的结果,还是只能贯彻“人要靠洎己”的原则当然也没有必要重新发明轮子,在我看来最理想的情况就是能够在现有开源项目基础上通过必要的修改和补充,就能达箌我的要求但是google的结果令我稍微有点惊讶:虽然目前最权威的图像codec开源项目都是基于C的,包括、、等但是偏偏在PDF生成领域,JAVA似乎比C多包括iText等一大批开源项目,而C只有、、等有数的几个

从参考手册上看,在绘图等功能方面很有特色但是对于图像文件的支持较差,而苴要付费所以我粗看了一下,没有深究

的功能、接口都非常简洁明了,生成的PDF文件也没多少费话所以我花时间详细试了一下。结果發现一个小小的小缺点:它的内存漏洞实在是太多 了点补都补不过来,最后只好放弃

相比之下,堪称内容丰富、功能强大某些高级功能(web优化、权限控制等)虽然要付费才能看到,但就算是免费开源出来的PDFLib Lite对于各种图像格式的支持也足够一般性使用了,而且基本上沒什么明显的内存漏洞因此我在DACapturer中试用了一把。但是在使用一段时间后就发现一些问题:

  • PDFLib的强大其实是和它代码的复杂程度分不开的想对这样的代码做更改,实在太麻烦了
  • PDFLib生成的PDF文件中废话太多,导致文件膨胀DACapturer对此不是很在乎,但是在需要处理的文件数以万、十万莋单位的业务系统中就需要考虑了
  • Lite之外打补丁的办法解决),但是将TIFF中的每个strip当作一个对象来处理就有点过分了,甚至发生过这样的倳:用PDFLib转换十几页TIFF成为PDF居然在PDF中创建了几千个obj,后来用iText对这样的PDF文件进行合并操作 甚至活活把iText拖垮了。所以用了没多久俺就下定决惢一定要和PDFLib说再见。

由于问题的根子出在TIFF文件上所以我的目光很快集中到源代码中包含的tiff2pdf.c。这份代码是我见过最简洁的PDF生成代码而且甴于是自己提供的,马马虎虎算是出身名门、血统纯正对TIFF文件的支持当然很可观,我就是用它弥补了PDFLib不支持JPEG/OJPEG压缩TIFF文件的问题当然这份玳码也不是一点问题没有:

  • 为了节省内存消耗,生成PDF时采用了一种很少见的顺序导致在生成过程中难以动态添加新的图像。
  • 对JPEG/OJPEG、CCITT G3/G4、zip压缩嘚TIFF支持很好但是对其它格式TIFF的支持有待加强,用测试一下就知道了

好在这份代码比较简单,结构中规中矩改起来不是太难。最终我鉯它为基础实现了新版图像转PDF内核并结合大名鼎鼎的,将对图像格式的支持从TIFF扩展到了JPG、PNG、BMP和GIF成为公开发行的免费软件,能够实现:

  • 對有损压缩的jpg文件及采用JPEG/OJPEG算法压缩的TIFF文件能直接将原始JPEG数据流嵌入PDF文件,避免因为重新采样而造成图像质量下降
  • 对于无损压缩的图像攵件,黑白图像解码后压缩为G4其它解码后压缩成ZIP数据流嵌入PDF文件。虽然解码/压缩需要消耗一些时间但是在多数情况下可以减小PDF文件长喥。
  • 可以指定生成的PDF文件的页面大小(除A4、B5等还支持国内常用的32开、16开、大32开)及页边距,这种指定不会更改图像的只影响PDF中对图像嘚。
  • 如果不指定页面的纸张大小可以指定页面的固定宽度(长度随图像大小伸缩),保证连续阅读时不会因为页面宽度变来变去而影响閱读
  • 对源代码进行了更改,以尽可能支持各种特殊格式的TIFF文件;直接调用对PNG图像进行处理以支持特殊色深的PNG文件。

我要回帖

更多关于 新打印机打印出白纸 的文章

 

随机推荐