Draw rectangle with Ghostscript (using PostScript language) - line

I'm trying to draw a rectangle and output it to a PDF using Ghostscript.
If I put the following PostScript code in a file named rect.eps, I get what I want:
newpath
100 100 moveto
0 100 rlineto
100 0 rlineto
0 -100 rlineto
-100 0 rlineto
closepath
gsave
0 0 0 setrgbcolor
fill
stroke
showpage
But if I try to include that PostScript into my Ghostscript-command, I just get a blank page:
gs -o rect.pdf -sDEVICE=pdfwrite -g300x300 -c "newpath 100 100 moveto 0 100 rlineto 100 0 rlineto 0 -100 rlineto -100 0 rlineto closepath gsave 0 0 0 setrgbcolor fill stroke showpage"
What am I doing wrong, shouldn't it be possible to draw a rectangle with Ghostscript?
Best Regards
Niclas

Stefan's comment is effectively correct.
You have set a media size in pixels of 300x300. Now given that the pdfwrite device's default resolution is 720 dpi, and you haven't changed that, this means that the media size is less than half an inch in each direction.
You have then drawn a rectangle, staring at 100,100 units on the page, and extending by 100 units in each direction. PostScritp units are 1/72 of an inch, so your rectangle's lower left corner begins at just over 1 inch up and right.
That's outside the half-inch square defined by your media, so the result is simply that the rectangle is drawn off the page.
If you don't set the media size Ghostscript will use its default, either A4 or Letter depending, and you will see the output. As to why it works when you make an EPS file, I have no idea, I expect there is content in the EPS that you haven't shared which is making a difference.
When creating a PDF file, which is a resolution-independent format, its better to specify the media size in resolution-independent units, like PostScript units, than pixels.
Note that your code has an additional problem, also mentioned by Stefan, the dangling gsave, which looks like it ought to have a grestore before the stroke. As it is the stroke will do nothing, I suspect you want:
gsave
0 0 0 setrgbcolor
fill
grestore
stroke
showpage

Related

Postscript: Rescaling and resizing page at the same time

For a plotting project of mine I was following the How-to by Eric Weeks to rescale my post-script page so that one unit matches 1 cm of length. The header of my PS file looks like this:
%!PS
matrix currentmatrix /originmat exch def
/umatrix {originmat matrix concatmatrix setmatrix} def
[28.3465 0 0 28.3465 0 0] umatrix
It does the job but the other thing I need is to resize the page from US Letter to A4. According to, e.g., Postscript - document size I should setpagedevice with something like:
<< /PageSize [595 842] >> setpagedevice
However I cannot make it work. When I put it in front of the matrix redefinition, it takes no effect. When I put it after the matrix redefinition (even translating the new size to cm) it resets the matrix scale and the page still comes out as US Letter, only the drawing is scaled down because the coordinates are now in pts.
How can I both rescale the page and define its size?
Edit: I am attaching a MWE presenting my problem. This draws a rectangle that would plot a box around the page, leaving a 10-mm margin if the page was A4-sized. On a letter-sized medium it shows how the paper is shorter but wider.
%!PS
matrix currentmatrix /originmat exch def
/umatrix {originmat matrix concatmatrix setmatrix} def
[28.3465 0 0 28.3465 0 0] umatrix
0.020000 setlinewidth
1.0 1.0 moveto 1.0 27.7 lineto 20.0 27.7 lineto 20 1.0 lineto 1.0 1.0 lineto
stroke
Is there another call of setpagedevice in the file which sets the letter format? The call executed last will win for the page size, and setting up the matrix differently has do be done after that call since it resets all graphic settings when setting up the page device.
If you cannot find where it is being called, you could redefine the setpagedevice operator in userdict. That might work or not, depending on how the whole PostScript file is constructed. In the redefinition you would create a new dict operand to setpagedevice, copy all entries but replace any PageSize by your desired value.
This might do:
userdict /setpagedevice {
dup length dict begin
{
1 index /PageSize eq {
pop [595 842]
} if
def
} forall
currentdict
end
setpagedevice
} bind put

Tiling an image over a page with ImageMagick with print margins?

I am trying to get ImageMagick to do something for me and I am running into a few problems. First, I am not understanding units of measure and such passed into ImageMagick and so my script is not producing what I need. Second, the way I am doing it is extremely inefficient. Running this script takes a very long time (the one you see below is slightly trimmed down from what I am running).
So to what I am doing... I have a number of svg files with icons in them. I am looking to generate a page for each of these files. The page generated will contain the icon tiled over the entire page with a margin on the side. I am looking for 1/2 inch tiles with 1/2 margins around the page which needs to be a US Letter (8 1/2 x 11 inch).
After reading a lot of the documentation this is what I came up with.
colors=(red blue purple yellow green black)
mkdir -p generated/icons/
for color in ${colors[#]}; do
images=`printf "source/icons/${color}.svg%.0s " {1..300}`
montage $images -tile 15x20 -page Letter+1+1 -units PixelsPerInch -density 2550x3300 \
generated/icons/${color}.pdf
done
So for each of my files I run montage. I use printf to repeat the image file name 300 times. I then tile this 15x20 times. 15x20 comes from 8.5 minus 1 inch margins = 7.5*2 = 15 and likewise (11-1)*2 = 20. 300 images come from 15*20. I then say I want this on a letter page offset 1x1. (This was my attempt at a margin) I say I am speaking in pixel per inch (but none of the units seem to match up). I set the dpi to 300 by the density command where 8.5*300 = 2550 and 11*300 = 3300.
I've been toying with other settings (geometry etc.) but none of these are working. And the units don't seem to make sense either... Right now my resultant pdf is a square etc...
How do I make tiled pages as such? Also is there a way for me to do this more efficiently? What I have thus far is very slow.
EDIT:
Some more information:
i:montage --version
Version: ImageMagick 6.8.8-10 Q16 x86_64 2015-03-10 http://www.imagemagick.org
tile image:
my current output:
Notice margins not right, is square not a letter page, also tiles as skewed
Given the PNG image you provided, and I presume you want a 1 inch border of white all around inside an 8.5x11 inch printed image. Thus the tiled width would be 7.5 inches and tiled height would be 10 inches.
1 in = 300 dpi so border thickness = 300 px = 2 tiles thick
11-1 = 10 inches tall for tiled region height = 10*300 = 3000 px
8.5-1 = 7.5 inches wide for tiled region width = 7.5*300 = 2250 px
1 tile = 0.5 inches at 300 dpi = 0.5*300 = 150 px
convert lUDbK.png -resize "150x150!" -write mpr:tile +delete -size 2250x3000 tile:mpr:tile -bordercolor white -border 300 -units pixelsperinch -density 300 tiled_page.png
Time to process was 1.75 sec on my Mac Mini.
This produces an image which is rather large. You will have to extract the image to see the border, since this page background is white.
(Note that PNG only supports pixelspercentimeter, but IM converts my specification of pixelperinch accordingly. So if you look at the meta data, it will probably show you some other density in units of pixelspercentimeter. But they will correspond to the desired 300 dpi.)

GraphicsMagick crop PDF

I've got a 8.5x11 PDF at 300dpi. It has a single UPC label in the top left corner of the PDF. Imagine that there could be 30 labels on a 1 sheet, but we just have 1 label.
I'm trying to crop the PDF to be just the size of the 1 label. So far I've got this
gm convert -density 300 single.pdf out.pdf
Which doesn't do any cropping. When I crop to say 300x100 it makes a 20MB file with 30000 pages.
I have not a clue how to use -crop to actually crop to the correct size. I need it to be 3.5inches by 1.125 inches.
Using the following input PDF (here converted to a PNG):
the following command will crop the label:
gm wiz.pdf -crop 180x50+1+1 cropped.pdf
This label is sized 180x50 pixels.
For an 8.5x11in PDF at 300 PPI you'd have a 2450x3300 pixels PDF (which I doubt you do, but that's another question) and you'd need to use -crop 1050x337+0+0 (more exactly, 1050x337.5+0+0 -- but you cannot crop half pixels!).
Note, the +0+0 part crops the top left corner. If you need offset to the right by N pixels and to the bottom by M pixels use +N+M...
Using ImageMagick instead...
You could also use ImageMagick's convert command:
convert wiz.pdf[180x50+1+1] cropped.pdf
Comment about image sizes...
One additional comment about this remark:
"I have not a clue how to use -crop to actually crop to the correct size."
There is no other real size for raster images than pixels. ABC pixels wide and XYZ pixels high...
There is no such thing as an absolute, real size for a digital image that you can measure in inches... unless you additionally can state the resolution at which a given image is rendered on a display or a print device!
An 8.50x11in sized image at 300 PPI will translate to 2550x3300 pixels.
However, if your image does not contain this amount of pixels (which is the real, absolute size of any raster image), you may still be able to render it at 300 PPI -- but its size in inches will be different from 8.5x11in!
So, whenever you want to crop, use the absolute number of pixels you want. Don't use resolution/density at all on your command line!

Why does this Ink Annotation show a curve instead of straight lines?

I created an ink annotation in the form of the letter Z, as shown above, however, the corners of the Z are rounded. Why does this happen? How can I avoid this additional beautification so that the corners stay sharp and the points are connected via a straight line?
PDF code:
%PDF-1.6
%μῦ
1 0 obj
<</Type/Catalog/Pages 2 0 R>>
endobj
2 0 obj
<</Type/Pages/Kids[3 0 R]/Count 1>>
endobj
3 0 obj
<</Type/Page/Parent 2 0 R/Resources<<>>/MediaBox[0 0 500 800]/Annots[4 0 R]>>
endobj
4 0 obj
<</Type/Annot/Subtype/Ink/Contents(<enter description here>)/InkList[[150 300 250 300 150 200 250 200]]/Rect[200 250 300 150]/P 3 0 R/F 4/C[1 0 0]>>
endobj
xref
0 5
0000000000 65536 f
0000000017 00000 n
0000000063 00000 n
0000000115 00000 n
0000000209 00000 n
trailer
<</Size 5/Root 1 0 R>>
startxref
374
%%EOF
I'm not sure what's going on here, and have no time to investigate right now.
But here are some immediate observations as additional data points:
Mac OS X's Preview.app shows the Z-shape with sharp edges.
Adobe Reader X and Adobe Acrobat X Pro (on Mac OS X) show the Z-shape with round edges.
Ghostscript v9.05 shows the Z-shape with round edges.
Ghostscript, self-compiled from today's Git repository, shows the Z-shape with round edges.
Update:
Ok, I had a quick look into the official ISO spec for PDF-1.7. It says this about the /Subtype /Ink annotations' /InkList:
An array of n arrays, each representing a stroked path. Each array shall be a series of alternating horizontal and vertical coordinates in default user space, specifying points along the path. When drawn, the points shall be connected by straight lines or curves in an implementation-dependent way.
(from Chapter 12.5.6.13 Ink Annotations, my emphasis)
So, it is completely 'legal' that one implementation shows straight lines, and the other one shows curves. :-(
Sigh...
Update 2:
So if you want to force the Z-shape to appear as straight lines for all implementations, you need to draw 3 different straight lines, each one represented by a different array, and put these 3 arrays into container array...
Change this part of your code:
/InkList
[
[150 300 250 300 150 200 250 200]
]
to this:
/InkList
[
[150 300 250 300]
[250 300 150 200]
[150 200 250 200]
]
and your Z-Shape will show sharp corners.
The solution is to create also the annotation appearance (the /AP entry in the annotation dictionary). If the annotation appearance, which draws the straight lines, is present in the PDF file then it will be used when displaying the file and you will get the same result in any viewer. If the appearance is not present then the viewer will construct the appearance based on annotation definition and in your case this viewer built appearance is implementation dependent.

Tile/concatenate high resolution PDF files with imagemagick

I've 9 high quality PDF files. I want to merge them into one large PDF of 3x3. I then want to turn this into a PNG file. I want to keep the resolution/sharpness during this process so that on the resulting PNG I can zoom right in and still see the fine detail. I thought I might do this with imagemagick but I'm struggling. Any ideas please?
I've tried this to merge them together to start with. It works, but the quality doesn't remain.
montage input_*.pdf -background none -tile 3x3 -geometry +0+0 output.pdf
Please note that file size and size of resulting image isn't an issue. I've no need to print it or anything like that. It's for viewing on a computer only.
Here is a sample of three of the PDF files:
1) https://www.dropbox.com/s/qc094jg1nkfk0jw/input_1.pdf?dl=0
2) https://www.dropbox.com/s/gb4u8r7bxg8lw2r/input_2.pdf?dl=0
3) https://www.dropbox.com/s/97dhi42wrvfxfd2/input_3.pdf?dl=0
Each PDF is 1071 x 1800 pts (using pdfinfo).
Thanks
James
Rather than stick with PDF and then merge and then convert to PNG, you may be better to extract the images as PNG in the first place and then concatenate the PNG files like this:
pdfimages -png input_1.pdf a
pdfimages -png input_2.pdf a
pdfimages -png input_3.pdf a
# Combine them side by side
montage a-*png -background none -tile 3x3 -geometry +0+0 output.png
# Or combine with "convert"
convert a-*.png +append result.png
The second document seems to have a mask...
pdfimages -list input_1.pdf
page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
1 0 image 12000 20167 icc 3 8 image no 9 0 807 807 1260K 0.2%
pdfimages -list input_2.pdf
page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
1 0 image 12000 20167 icc 3 8 image no 9 0 807 807 5781K 0.8%
1 1 smask 12000 20167 gray 1 8 image no 9 0 807 807 230K 0.1%
pdfimages -list input_3.pdf
page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
1 0 image 12001 20167 icc 3 8 image no 9 0 807 807 2619K 0.4%