7

I am trying to write a document in postscript.

Thus far I've been able to write simple text, and work with lines and shapes.

I'm now trying to add some images to the document. After searching on-line I can't seem to find any clear way to do this.

the snip it below is a hello world:

%!PS
/Times               
20 selectfont         
20 800 moveto         
(Hello World!) show
showpage 

All I want to do is simply insert an image (eg PNG, JPG, GIF) by specifying the x and y, co-ordinates.

Any help would be much appreciated.

Darknight
  • 2,460
  • 2
  • 22
  • 26
  • 1
    There is no direct way for postscript o read these formats - but see @lhf answer bellow. If you want to add the image directly, check my answer to http://stackoverflow.com/questions/4924819/converting-writing-a-bufferedimage-to-postscript – jsbueno Feb 12 '11 at 13:14

4 Answers4

11

There is a simple method and Postscript does support the jpeg format. If you are using ghostscript you may have to use the -dNOSAFER option to open files. Here is an example:

gsave
 360 72 translate     % set lower left of image at (360, 72)
  175 47 scale         % size of rendered image is 175 points by 47 points
  500                   % number of columns per row
  133                    % number of rows
  8                    % bits per color channel (1, 2, 4, or 8)
  [500 0 0 -133 0 133]       % transform array... maps unit square to pixel
  (myJPEG500x133.jpg) (r) file /DCTDecode filter % opens the file and filters the image data
  false                 % pull channels from separate sources
  3                    % 3 color channels (RGB)
  colorimage
grestore
Hath995
  • 821
  • 6
  • 12
  • How about making it a procedure taking (filename,x,y,wid,ht) ? It could also take an additional parameter to specify which corner should be at (x,y). If you're doing quick-and-dirty typesetting, the top-left corner is more straightforward to work with. – luser droog Sep 23 '11 at 00:48
  • It could be placed in a procedure but most of the above code is just putting data in the stack in the proper order for the colorimage command. The bottom left corner isn't really a choice it is defined by postscript. Postscript defines 0,0 as the bottom left of the page and so postscript native methods are also bottom-left centric if you catch my gist. You could choose to define x,y as the top left but your function would have to convert to bottom left coordinates for you essentially. – Hath995 Sep 23 '11 at 11:48
  • Yeah, I'm not complaining or anything. But consider the level of the questioner... Actually I take it all back! Doing this would be a perfect exercise. And you've given all that's needed! – luser droog Sep 23 '11 at 12:41
3

Use a program like convert and then remove any extra code it generated.

lhf
  • 70,581
  • 9
  • 108
  • 149
  • 2
    The code generated by *pnmtops* may be easier to understand. See http://netpbm.sourceforge.net/doc/pnmtops.html – lhf Feb 12 '11 at 12:34
  • For straight bitmaps, convert to .xbm is pretty handy, but [the bits in each byte are backwards](http://groups.google.com/group/comp.lang.postscript/browse_thread/thread/35a45d1ae70162e8). – luser droog Dec 28 '11 at 06:32
1

You can download the PostScript Language Reference, third edition from adobe (this is the "bible book" for postscript). Chapter 4.10 Images would be a good starting point.

hlovdal
  • 26,565
  • 10
  • 94
  • 165
0

Is this a late answer! The problem with -dNOSAFER prevented me from using the other solutions, so I did the following:

Use Python to read the JPG file as binary and make it a string, compatible with /ASCIIHexDecode:

''.join(["%02x" % ord(c) for c in open(filename, "rb").read()])

Then instead of reading and decoding the image file from the postscript file, paste the above computed string in the postscript file, and filter it, first through /ASCIIHexDecode then /DCTDecode:

(ffd8ffe000104a46494600010102002700270000ffdb004300030202020202030202020303030304060404040404080606050609080a0a090809090a0c0f0c0a0b0e0b09090d110d0e0f101011100a0c12131210130f101010ffdb00430103030304030408040408100b090b1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010ffc00011080010001003011100021101031101ffc400160001010100000000000000000000000000060507ffc40026100002020201030207000000000000000001020304051106071221001315163132414252ffc400160101010100000000000000000000000000070403ffc4002911000201030105090100000000000000000102030004210711123151531314324142617381d1d3ffda000c03010002110311003f00de311d00e0478be19acddc79b0f8ba734aef8aa8a59a4af1c9bdc96159beef275e4efd1ccfa5f2aceea2f8e09f41e7f252a47ab4c4093ba71ceced387b7828b724e87705b588c8478ecac114e28d89e36f83d65d7643ee7eb60b03a23f1f5dff002daaacf4ae479954df1e3d33fd2b593599628d89b0071d5fae9d3bc5750b8a3f1ae3cc9cd3031b4789c689236ce568de374af543ab21b51b2b03138208076a3cef4c8b935acaf3bb05c12685036e285e550b3bccf8a41c7b2327ce78c9a6188b917b2995ab20676a8102af6dc76624c680011f9d8f0005095da5b491ccaec303f0d4f292ebba01cecf23cc57ffd9>)
  /ASCIIHexDecode
  filter             % ascii to bytes
  0 dict
  /DCTDecode         % jpg to explicit
  filter

the above snippet replaces (myJPEG500x133.jpg) (r) file /DCTDecode filter in the otherwise very helpful @Hath995 answer.


if you want something else than JPEG but still RGB (i.e.: you want something for which postscript has no decoder), and you can use Python to prepare your postscript file, you can use PIL, like this (it ignores the transparency byte, which is a on/off operation in postscript):

import PIL.Image
i = PIL.Image.open("/tmp/from-template.png")
import itertools
''.join(["%02x" % g 
         for g in itertools.chain.from_iterable(
                    k[:3] for k in i.getdata())])

for indexed files I would not know, but it can't be difficult to work it out.

mariotomo
  • 9,438
  • 8
  • 47
  • 66