如何更改 PDF/PostScript 文件中的行宽

Posted

技术标签:

【中文标题】如何更改 PDF/PostScript 文件中的行宽【英文标题】:How to change the width of lines in a PDF/PostScript file 【发布时间】:2019-04-01 22:33:53 【问题描述】:

我经常需要处理技术图纸(机械工程),并且它们通常带有无法正确打印的彩色线条。因此我编写了下面列出的批处理脚本。它使用ghostscript将图纸转换为黑白;请注意,灰度是不够的,因为它们在激光打印上可能几乎看不到。 批处理脚本甚至可以处理拖放到上面的多个文件。

现在我遇到一大堆图纸,它们的线宽似乎是细线——在激光打印上几乎看不到。

我尝试采用该脚本但无济于事!

我试过了

-c "save /zz setlinewidth bind def /setlinewidth  10 mul zz bind def"

-c "/setlinewidth  10  bind"

等等。

ghostscript改变线宽的正确参数是什么?

我还附上了我用来试验的 PostScript 文件。

非常感谢!!!

L.

::  PDFmono.bat
@echo off
if [%1]==[] goto :eof

set GS_EXEC=gswin64c.exe

:loop

set INPUT_FILE=%1
set INTERMEDIATE_FILE=%temp%\%~n1.ps
set OUTPUT_FILE=%~dp1\%~n1_mono%~x1
echo ==============================================================================
echo Converting PDF to monochrome:
echo %INPUT_FILE%
echo ------------------------------------------------------------------------------

%GS_EXEC% ^
    -sOutputFile="%INTERMEDIATE_FILE%" ^
    -sDEVICE=ps2write ^
    -dNOPAUSE -dBATCH -dSAFER ^
    "%INPUT_FILE%"

%GS_EXEC% ^
    -sOutputFile="%OUTPUT_FILE%" ^
    -sDEVICE=pdfwrite ^
    -c "/setrgbcolor  pop pop pop 0 setgray  def /setcmykcolor  pop pop pop pop 0 setgray  def /sethsbcolor  pop pop pop 0 setgray  def" ^
    -dNOPAUSE -dBATCH -dSAFER ^
    "%INTERMEDIATE_FILE%"

del "%INTERMEDIATE_FILE%"
echo ------------------------------------------------------------------------------
echo Done! Monochrome PDF saved as
echo %OUTPUT_FILE%
echo ==============================================================================

shift
if not [%1]==[] goto loop

【问题讨论】:

好像我不能附加文件,但是发布的文件太长了 174914 个字符!? 如果您正在处理的脚本太大而无法在此处发布,请将其删减,直到您拥有我们复制您的问题所需的基本要素。见How to create a Minimal, Complete, and Verifiable example。 @SomethingDark:感谢您的建议!不幸的是,它是由 Ghostscript 创建的 PostScript 文件;我无法手动缩小它。 如果问题与 ghostscript 参数有关,那么您不需要 batch-file 标记,因为您没有任何批处理文件问题。因此,我删除了不必要的标记,但由于该问题可能涉及通过 cmd.exe 传递给可执行文件的参数,因此我将其替换为 cmd 标记。此外,由于您的问题似乎是关于如何通过其 CLI 与第三方产品进行交互,您实际上是在请求参考材料或免费的代码编写服务。如果是这种情况,请注意这两种情况都不是这里的主题。 @Compo 你说得对,这不是批次问题! PostScript 是图灵完备的编程语言,因此我认为这个问题适合这里。 【参考方案1】:

PDF 和 PostScript 是不同的东西,我不清楚您使用哪个作为输入。如果是 PDF,那么您基本上无法更改线条的宽度。如果是 PostScript,那么在一定的范围内,你可以。

首先要注意的是,PostScript 程序完全有可能(并且并非完全不常见)故意破坏您为更改颜色而执行的那种运算符重新定义。程序可以直接从 systemdict 显式加载运算符,这将绕过您对运算符的重新定义。您的定义将存储在 userdict 中(因为您没有指定任何其他字典)。您不能覆盖 systemdict 中的定义,因为它是只读的。您可以使用-dWRITESYSTEMDICT,但我强烈建议您不要使用,因为这是一个巨大的安全漏洞。

重新定义 setlinewidth 不起作用的原因几乎可以肯定是因为 PostScript 程序将执行类似0 setlinewidth 的内容。这在 PostScript 中被定义为在设备上绘制尽可能窄的线,通常为 1 个像素宽。

看看你的两个例子:

0 乘以 10 的结果是……零!这不会改变线宽。请注意,您还执行了保存,但没有执行恢复,这很浪费。你不需要保存。

在第二个示例中,您将原始参数留在了堆栈中,因此可能会破坏程序执行,并且您实际上并没有改变图形状态,因为您没有调用系统 setlinewidth。这也将 10 留在堆栈中。

类似:

%% Grab a copy of the current setlinewidth
%%
/system_setlinewidth /setlinewidth load def

%% Define a version of setlinewidth which expands hairlines
%%
/setlinewidth 
  dup            %% copy the linewidth parameter
  0 eq           %% Test if its zero, defined as a hairline (consumes the copy)
  
    pop 10       %% discard the linewidth and replace it with 10
  
  system_setlinewidth  %% Still need to actually execute the setlinewidth
 bind def

可能会工作。请注意,我没有对此进行测试。

这个问题完全是 Ghostscript 和 PostScript 的主题,因为它涉及 PostScript 编程问题。它不是“monchrome”、“cmd”、“batch-file”和(可能)PDF 的主题。

虽然没有办法使用 Ghostscript 将此技巧应用于 PDF 文件,但同样存在潜在问题;零宽度线被定义为细线,并且总是一个像素宽,无论设备的分辨率如何。如果可以的话,您应该向创建这些文件的人推荐他们不要这样做,除非他们有非常好的理由!

【讨论】:

在我的行业中,这两个问题(带有彩色线条和/或细线的 PDF 格式的技术图纸)都很常见。原因是人们将 CAD 图纸绘制成 PDF 文件时不使用(正确的)笔式文件(笔式绘图仪的遗留物)。你是对的,我没有明确说明原始文件是(总是)PDF文件。谢谢你的回答! 单色问题已经解决。它使用 Ghostscript 将 PDF 文件转换为 PostScript,并将其保存到临时目录。然后它再次调用 Ghostscript 将 PostScript 保存回 PDF,同时执行 /setrgbcolor pop pop pop 0 setgray def /setcmykcolor pop pop pop pop 0 setgray def /sethsbcolor pop pop pop 0 setgray def 也许它没有不适用于所有文件,但它适用于我迄今为止尝试过的文件。 好吧,如果你已经乐于这样做了,那么你可以对线宽做同样的事情。请注意,如果您的任何 PDF 文件包含透明度,那么事情就会大错特错。页面将被渲染为位图,这将导致文件巨大而缓慢,您将无法更改颜色或线宽(因为它们将被“烘焙”到图像中) 如果 10 应该是最小绘制宽度,那么 10 lt 可能是比 0 eq 更好的测试。 10 是一个随机抽取的数字,0 lt 表示它只扩展 hairlines 即 setlinewidth 设置为 0 的情况,这意味着在任何设备上都只有一个像素.这就是评论所说的;-)

以上是关于如何更改 PDF/PostScript 文件中的行宽的主要内容,如果未能解决你的问题,请参考以下文章

选中复选框后如何更改datagridview中的行颜色

Bash:根据另一个文件中的行更改文件头[重复]

MySQL - 如何更改表中的行顺序

如何根据值更改jquery dataTable中的行颜色

如何使用jQuery更改文本区域中的行数

如何在 Sqlite 数据库中的特定数据上更改 Listview 中的行颜色