使用 ConTeXt 修改既有 PDF 文档的元数据

使用 ConTeXt 裁剪既有 PDF 文档页面

Garfileo posted @ 2011年9月30日 19:33 in ConTeXt 笔记 with tags ConTeXt MkIV PDF 裁剪 , 7607 阅读

上一集 [1]  介绍了使用 ConTeXt 调整既有 PDF 文档的元数据,所用的方法是将既有 PDF 文档的全部页面作为 ConTeXt 生成的 PDF 文档的插图。本集也利用了类似的方案来实现既有 PDF 文档的页面裁剪。

为什么要裁剪 PDF 页面

不是很清楚他人是否有 PDF 页面裁剪的需求,对于我而言,通常在两种情况下需要这样做。一种情况是将 PDF 页面中的图形提取出来作为自己所写文档的插图;另一种情况是我想在自己可怜兮兮的 1204x600 分辨率的上网本里阅读一些 PDF 文档。

单幅页面裁剪

如果想将 PDF 页面中的图形提取出来,最直观的做法就是将图形视为矩形区域,然后裁掉它之外的所有区域。例如对于下图所示的 PDF 页面,若要提取其中的插图,可能 inkscape 之类的工具会更方便一些。不过,这里我坚持使用 ConTeXt,主要是因为它是后面要讲的 PDF 页面批量裁剪的基础。

看下面的 ConTeXt 文稿:

\starttext

\startTEXpage
\clip[nx=180,ny=240,x=40,y=30,sx=125,sy=68]
     {\externalfigure[autotools-book.pdf][page=40]}%
\stopTEXpage

\stoptext

其中,\startTEXpage ... \stopTEXpage 命令可以让页面即无页码也无白边,且其尺寸恰好可以包含是我们所要提取的图片。

\clip 命令是对 \externalfigure 载入的 autotools-book.pdf 的第 40 页进行裁剪。要注意的是 \clip 命令的参数,即:

  • \(n_x\), \(n_y\) 表示将 \externalfigure 载入的 PDF 页面纵横划分为 \(n_x n_y\) 个单元,可将其视为 PDF 页面的分辨率;
  • \(x\), \(y\) 表示裁剪区域的左上角坐标分量,皆为整数,且 \(x\in [1, n_x]\), \(y\in [1, n_y]\);
  • \(s_x\), \(s_y\) 表示裁剪区域的宽度与高度,皆为整数,且 \(s_x\in [1, n_x]\), \(s_y\in [1, n_y]\)。

也许你会问这些该死的参数应当如何取值?

对于 \(n_x\) 与 \(n_y\),我通常是根据 PDF 页面尺寸的近似值来定。例如对于上例,PDF 页面的宽度近似为 18 cm,高度近似为 24 cm,于是便将 \(n_x\) 与 \(n_y\) 分别设为 180 与 240。这样,\((x, y)\) 与 \((s_x, s_y)\) 的精度便是 1 mm.

由于 \((x, y)\) 与 \((s_x, s_y)\) 标定了页面裁剪的保留区域,所以它们的取值决定了图片提取精度。你可以使用 inkscape, gimp 之类的工具,根据页面尺寸比例计算出它们,也可以用自身的视觉识别并配合大脑进行几次迭代从而获得符合要求的值。

PDF 页面批量裁剪

一般而言,批量裁剪 PDF 页面主要用于去除 PDF 页面周边的空白区域,以缩减页面尺寸从而节省屏幕空间为目的。下面以《Gnuplot in action》这本书为例,实践一下页面的批量裁剪。

《Gnuplot in action》这本书的排版很精美,但是因为页面周边空白区域较大(见下图),对于分辨率较小的屏幕阅读这本书就有些吃力了。

下面的 ConTeXt 文稿可以对这本书进行白边裁剪。

\define\MyDocument{gnuplot-in-action.pdf}
\getfiguredimensions[\MyDocument] 

\def\ClipNX{210}
\def\ClipNY{297}
\def\ClipX{32}
\def\ClipY{40}
\def\ClipSX{154}
\def\ClipSY{210}

\setuplayout[backspace=0cm,
             cutspace=0cm,
             topspace=0cm,
             bottomspace=0cm,
             header=0cm,
             footer=0cm,
             width=middle,
             height=middle]

\starttext

\dorecurse\noffigurepages{%
\startTEXpage
\clip[nx=\ClipNX,ny=\ClipNY,x=\ClipX,y=\ClipY,sx=\ClipSX,sy=\ClipSY]
     {\externalfigure[\MyDocument][page=\recurselevel]}%
\stopTEXpage%
}

\stoptext

裁剪后的结果如下图所示。

[1] 使用 ConTeXt 修改既有 PDF 文档的元数据

转载时,希望不要链接文中图片,另外请保留本文原始出处:http://garfileo.is-programmer.com

  • 无匹配
Avatar_small
views63 说:
2011年9月30日 20:18

最近重新去排版 Learn You a Haskell for Great Good! 遇到断页异常,找不到原因无法解决。在页码 14 http://goo.gl/Tke73

Avatar_small
Garfileo 说:
2011年9月30日 20:27

估计是 typing 闹的,取消 typing 的样式设置试试

Avatar_small
views63 说:
2011年9月30日 20:55

@Garfileo: 果然是,取消后正常了。那个 learnyouahaskell.pdf 也用了 typing 的样式设置,但没出现这种情况,不知道怎么设置的或者当时的 CTX 不会出错。

Avatar_small
Garfileo 说:
2011年10月01日 10:44

@views63: 自动分页出故障的时候,可以尝试手动分页。

Yue Wang 说:
2011年10月10日 07:53

對於對開的,需要奇偶分別裁。我先前也寫過代碼實現。不過acrobat可以循環做這些。

Avatar_small
Garfileo 说:
2011年10月10日 08:48

@Yue Wang: 嗯,示例 gnuplot-in-action.pdf 本来是分奇偶页来裁的。为了代码的可读性,我个简化成单面了,幸好它的奇偶页面的版心位置相差不大。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter