Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to adjust BoundingBox of an EPS file?

I want to crop main area of a PS or PDF file to create an EPS file without white space. Commands of ghostrcipt, ps2pdf, epstools can crop the main drawing out of the document file.

The problem is that they only crop in its original form, but I want to create an EPS file with BoundingBox 0 0 x y; cropped and moved to the bottom left corner.

The difference i when we want to insert the resulting EPS file inside a PS document. When having BoundingBox x0 y0 x y, the PS document inserts the EPS file at point x0 y0, instead of where we are.

EXAMPLE:

Consider a simple PS file as

%!
/Times-Roman findfont 
11 scalefont setfont

72 700 moveto
(This is a test)show

if converting it to EPS with a command like

ps2eps test.ps test.eps

It will produce

%!PS-Adobe-2.0 EPSF-2.0
%%BoundingBox: 72 700 127 708
%%HiResBoundingBox: 72.000000 700.000000 127.000000 707.500000
%%EndComments
% EPSF created by ps2eps 1.68
%%BeginProlog
save
countdictstack
mark
newpath
/showpage {} def
/setpagedevice {pop} def
%%EndProlog
%%Page 1 1
/Times-Roman findfont 
11 scalefont setfont
72 700 moveto
(This is a test)show
%%Trailer
cleartomark
countdictstack
exch sub { end } repeat
restore
%%EOF

It has been cropped in its original coordinates, and the resulting BoundingBox is 72 700 127 708. Now if trying to insert this EPS file within a PS document, it tries to nest at this coordinate.

It will be useful if creating an EPS file with BoundingBox: 0 0 55 8. Of course, all drawing coordinates (here moveto) must be modified with this new reference.

NOTE: As stated, my purpose from fixing the BoundingBox reference point is to make it importable within PS document. Thus, an alternative answer to this question is: how to insert an EPS file inside PS document regardless of its BoundingBox.

For example, how to insert this EPS file at location 200 200 255 208 of a PS document. I try to insert the EPS with the following code, but it will not work unless the BoundingBox is started from 0 0:

200 200 translate 
save 
/showpage {} bind def 
(test.eps)run 
restore
like image 784
Googlebot Avatar asked Oct 01 '12 23:10

Googlebot


2 Answers

What about simply un-translating?

-72 -700 translate

Either in the eps itself, or in the prep section before the inclusion?


AWKward!

The following typescript illustrates an awk script which performs the desired modifications to the eps, guided by the DSC comments (just like Mama used to do!).

The advantage is: if you can guarantee that the input EPS conforms sufficiently to DSC to provide these markers, this approach will be orders-of-magnitude faster than passing the file through ghostscript.

Simplicity is both the advantage and the limitation of this program. It scans for DSC comments, extracts values from the BoundingBox comment, suppresses the HiResBoundingBox, and adds postscript 'translate' and 'rectclip' commnds just after the Page comment. This should produce the correct results so long as the EPS really is bona-fide. But the ghostscript approach in the other answer will produce results on input files with less reliable DSC-conformance (because it's not taking shortcuts, it treats DSC as comments and completely ignores them).

Strictly speaking the 'rectclip' shouldn't be necessary, but the question asks that the output be "cropped".

592(1)11:27 AM:~ 0> cat epscrop.awk
/%%BoundingBox: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*)/{x=$2;y=$3;w=$4-x;h=$5-y;print $1,0,0,w,h}
!/%%BoundingBox:/&&!/%%HiRes/{print}
/%%Page /{print -x,-y,"translate"; print 0,0,w,h,"rectclip"}


593(1)11:27 AM:~ 0> awk -f epscrop.awk etest.eps
%!PS-Adobe-2.0 EPSF-2.0
%%BoundingBox: 0 0 55 8
%%EndComments
% EPSF created by ps2eps 1.68
%%BeginProlog
save
countdictstack
mark
newpath
/showpage {} def
/setpagedevice {pop} def
%%EndProlog
%%Page 1 1
-72 -700 translate
0 0 55 8 rectclip
/Times-Roman findfont
11 scalefont setfont
72 700 moveto
(This is a test)show
%%Trailer
cleartomark
countdictstack
exch sub { end } repeat
restore
%%EOF
like image 178
luser droog Avatar answered Sep 22 '22 17:09

luser droog


To convert it to an EPS with the BoundingBox-style you want, I would use Ghostscript and let the EPS make a roundtrip: EPS => PDF => EPS.

The trick is to ensure that the PDF uses a media size that is the same as the BoundingBox width and height are by adding the -dEPSCrop param.

These two commands create your 'EPS without white space':

1st step: convert EPS to PDF:

gs                   \
  -o so#12682621.pdf \
  -sDEVICE=pdfwrite  \
  -dEPSCrop          \
   so#12682621.eps

2nd step: convert PDF back to EPS:

gs                                \
  -o so#12682621.roundtripped.eps \
  -sDEVICE=epswrite               \
   so#12682621.pdf 

To test the fidelity of your resulting EPS, you could use ImageMagick's compare to show the differences, pixel-wise in red, as a PNG file:

 compare                      \
   -density 600               \
    12682621.roundtripped.eps \
    12682621.eps              \
   -compose src               \
    12682621.png

which results in: enter image description here

You'll notice that there are some pixel differences. They are caused by the value of 707.500000 from the %%HiResBoundingBox, which leads to a rounding error later on (PNG can't have 'half pixels').

like image 34
Kurt Pfeifle Avatar answered Sep 22 '22 17:09

Kurt Pfeifle