How to change the width of lines in a PDF/PostScript file

笑着哭i 提交于 2021-02-11 13:29:00

问题


I regularly need to handle technical drawings (mechanical engineering) and they often come with colored lines, which can't be printed properly. Therefore I wrote the batch script listed below. It uses ghostscript to convert drawings to black & white; note that greyscales aren't sufficient, as they might be barely visible on a laser print. The batch script even handles multiple files dragged and dropped on it.

Now I encounter a large bunch of drawings which appear to have linewidths of hairline – hardly visible on a laser print.

I tried to adopt the script but to no avail!

I tried

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

-c "/setlinewidth { 10 } bind"

among others.

What are the correct parameters for ghostscript to change the linewidths?

I also attached the PostScript file I use to experiment with.

Thank you very much!!!

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

回答1:


PDF and PostScript are different things, and it isn't clear to me which you are using as your input. If its PDF then you basically can't change the width of lines. If its PostScript then, within certain limits, you can.

First thing to note is that its entirely possible (and not totally uncommon) for PostScript programs to deliberately defeat the kind of operator re-definition you are performing to change colour. A program can explicitly load the operators directly from systemdict, which will bypass your redefinition of the operators. Your definitions will be stored in userdict (because you haven't specified any other dictionary). You can't override teh definitions in systemdict because that is read-only. You could use -dWRITESYSTEMDICT but I'd strongly recommend that you don't, because that's a massive security hole.

The reason your redefinition of setlinewidth doesn't work is almost certainly due to the fact that the PostScript program will be executing something like 0 setlinewidth. This is defined in PostScript as drawing the narrowest possible line on the device, usually one pixel wide.

Looking at your two examples;

Multiplying 0 by 10 results in... zero! Which doesn't alter the line width. Note that you've also executed save, but not restore, which is wasteful. You don't need the save.

In the second example you've left the original parameter on the stack, so potentially corrutped the program execution, and you haven't actually altered the graphics state because you haevn't called the system setlinewidth. Which also leaves the 10 on the stack.

Something like :

%% 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

Would probably work. Note that I haven't tested this. Regarding files, if you can't paste it in here, then put it somewhere public (eg DropBox) and put the URL in the question. For future reference.

The question is entirely on-topic for both Ghostscript and PostScript since it involves a PostScript programming question. Its not on-topic for 'monchrome', 'cmd', 'batch-file' and (probably) PDF.

There is no way to apply this trickery to a PDF file with Ghostscript though, and the same potential problem applies; zero width lines are defined as hairlines and are always one pixel wide, no matter what the resolution of the device. If you can you should recommend to the people creating these files that they don't do that unless they have an awfully good reason!



来源:https://stackoverflow.com/questions/55464503/how-to-change-the-width-of-lines-in-a-pdf-postscript-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!