How include img in postscript

后端 未结 3 1805
盖世英雄少女心
盖世英雄少女心 2020-12-10 08:03

I want to add image to my postscript code

%!PS-Adobe-3.0

/Times-Roman findfont
12 scalefont setfont

50 700 moveto
(text) show
showpage

bu

相关标签:
3条回答
  • 2020-12-10 08:43

    I would suggest a simple way - run an EPS file.
    First, convert the image to EPS, ex. myimage.eps, save it in myfolder and then modify your code to define placeEPS operator and display myimage.eps by using it.

    %!PS-Adobe-3.0
    
    % Place EPS image definition
    % Syntax: <file> <scale> <x> <y> placeEPS
    % =============================================================
    /placeEPS 
    {
        userdict begin
    
        /__be_state     save            def
        /__ds_count     countdictstack  def
        /__os_count     count 5 sub     def
        /showpage       {}              def
    
        initgraphics
        translate 
        dup scale 
        run
    
        count           __os_count sub  { pop } repeat
        countdictstack  __ds_count sub  { end } repeat
                        __be_state              restore
        end
    } bind def
    % =============================================================
    
    % Your old code starts here
    /Times-Roman findfont
    12 scalefont setfont
    50 700 moveto
    (text) show
    
    % Now mark myimage.eps scaled to 100% at position 100, 100
    (myfolder/myimage.eps) 1 100 100 placeEPS
    
    showpage
    

    Now convert to PDF by Acrobat Distiller or GhostScript.
    You can also use this approach to place a full-page canvas to a document.

    0 讨论(0)
  • 2020-12-10 08:55

    ;tldr

    skip to the middle and start reading from Simpler Workflow to the end.

    convert to xbm, hack with vi, inline data with {currentfile} image

    It is documented in the Postscript Language Reference Manual, but the information can be a little hard to digest.

    As Ken says, you need to use the image operator. I usually go for the "old school" form which is

    width height bits-per-pixel matrix proc   image   ‐

    For some random image file, you usually want to use something like convert from ImageMagick to get a textual format. Of course you could also just convert it to an eps, but to learn, you've got to stick your fingers in it.

    % convert image.png image.xbm
    

    This will give you a file like:

      1 #define glasses_width 320
      2 #define glasses_height 240
      3 static char glasses_bits[] = {
      4   0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      5   0x00, 0x00, 0x00, 0x00, 0x45, 0x65, 0xDB, 0x65, 0xB5, 0x6F, 0xBF, 0xEF,
      6   0xFF, 0xFF, 0xFF, 0xBF, 0xB5, 0xED, 0x3C, 0xBF, 0xB3, 0xDB, 0xAD, 0xF6,
      7   0xE6, 0x4A, 0xAA, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
      8   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0xA8, 0x66, 0xD6,
      9   0xDF, 0xF9, 0xF7, 0xBF, 0xFF, 0xFD, 0xFF, 0xFE, 0xFF, 0x7F, 0xFB, 0xEA,
     10   0xDD, 0x5A, 0x9A, 0x69, 0xB9, 0xBE, 0x55, 0x65, 0x00, 0x00, 0x00, 0x00,
    ...
    803   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    804   };
    

    So, in vi, do a few things like

    :%s/^#/%#/         #comment-out the #defines
    :g/[{}]/d          #delete the array brackets
    :%s/0x//g          #remove the 0x prefixes
    :%s/, //g          #remove the spaces
    

    Giving something like this:

      1 %#define glasses_width 320
      2 %#define glasses_height 240 
      3   000000000003000000000000
      4   000000004565DB65B56FBFEF
      5   FFFFFFBFB5ED3CBFB3DBADF6
      6   E64AAABA0000000000020000
      7   000000000000000099A866D6
      8   DFF9F7BFFFFDFFFEFF7FFBEA
      9   DD5A9A69B9BE556500000000
     10   000C00000000000000000000
    ...
    802   000000000000000000000000
    

    Then you use the numbers in the image call, trim those lines too, and insert the data directly after these lines

    %width height depth [ x-scale x-skew y-skew y-scale x-offset y-offset ]=matrix 
    320    240    1     [ 1       0      0      -1      0        240 ]
    %  {proc-yielding-string-data}                  call(image)
       { currentfile 80 string readhexstring pop }  image
    

    This assumes that your bitmap data has y increasing downwards. This approach can be tweaked for other ascii formats, as long as you can get some kind of dump of the raw samples. Embedding compressed images with decoder code is a big can of worms I suggest you avoid for a while. (Mostly because I don't know how to do this, yet. I've been avoiding it like a big can o' worms. :D)


    I checked my advice above, and there is a big snag I forgot. Postscript likes its bitmaps in big-endian bytes. That is, bit 7 is the leftmost and bit 0 is the rightmost bit. This is the reverse of the xbm format. So, the completed program introduced above is:

    %!
    %reverse the bits in a byte
    /reverse {               % b
        dup 1 and            % b b0          % explode the bits
        1 index 2 and        % b b0 b1
        2 index 4 and        % b b0 b1 b2
        3 index 8 and        % b b0 b1 b2 b3
        4 index 16 and       % b b0 b1 b2 b3 b4
        5 index 32 and       % b b0 b1 b2 b3 b4 b5
        6 index 64 and       % b b0 b1 b2 b3 b4 b5 b6
        8 7 roll 128 and     % b0 b1 b2 b3 b4 b5 b6 b7
        -7 bitshift exch     % b0 b1 b2 b3 b4 b5 b7-7=0' b6  % shift and combine
        -5 bitshift or exch  % b0 b1 b2 b3 b4 b0'|b6-5=1' b5
        -3 bitshift or exch  % b0 b1 b2 b3 b0'|b1'|b5-3=2' b4
        -1 bitshift or exch  % b0 b1 b2 b0'|b1'|b2'|b4-1=3' b3
        1 bitshift or exch   % b0 b1 b0'|b1'|b2'|b3'|b3+1=4' b2
        3 bitshift or exch   % b0 b0'|b1'|b2'|b3'|b4'|b2+3=5' b1
        5 bitshift or exch   % b0'|b1'|b2'|b3'|b4'|b5'|b1+5=6' b0
        7 bitshift or        % b0'|b1'|b2'|b3'|b4'|b5'|b6'|b0+7=7'
    } def
    
    320 240 1  % width height bitdepth
    [ 1 0 0 -1 0 240 ]  % 1-to-1 matrix with descending y, offset by max_y
    { %proc-yielding-string
        currentfile 80 string  % file string
        readhexstring pop  % string         read a line of hex data from THIS FILE
        0 1 2 index length 1 sub  % string 0 1 strlen-1
        {  % string index
            2 copy 2 copy  % str i str i str i
            get reverse    % str i str i rev(str_i)
            put  % str' i
            pop % str'                      % reverse each char (byte)
        } for                               % loop over chars in string
    } image
      000000000003000000000000
      000000004565DB65B56FBFEF
      FFFFFFBFB5ED3CBFB3DBADF6
      E64AAABA0000000000020000
      000000000000000099A866D6
      DFF9F7BFFFFDFFFEFF7FFBEA
      ...
    

    Full program available with full image data appended here.


    Simpler workflow

    Simpler, but still "hand-on", is to convert to pbm which uses the same bit-ordering conventions as postscript. Then xxd -ps will produce a "postscript" hexdump. The following three examples all use hex data prepared this way. But this method still requires you to manually measure the length of the header (use xxd to find the byte offset after the whitespace-char after the width and height).

    %!
    % swar.ps
    %
    %image example
    %image origin:  http://upload.wikimedia.org/wikipedia/commons/thumb/2/23/Spacewar%21-PDP-1-20070512.jpg/320px-Spacewar%21-PDP-1-20070512.jpg
    %
    % bash commands to prepare image file:
    %
    % $ wget http://upload.wikimedia.org/wikipedia/commons/thumb/2/23/Spacewar%21-PDP-1-20070512.jpg/320px-Spacewar%21-PDP-1-20070512.jpg
    % $ identify 320px-Spacewar\!-PDP-1-20070512.jpg 
    % $ convert 320px-Spacewar\!-PDP-1-20070512.jpg spacewar.pbm
    % $ xxd -ps spacewar.pbm > spacewar.asc
    % % gs swar.ps
    
    
    /infile (spacewar.asc)(r)file def
    /buf 256 string def
    
    % use $ xxd spacewar.pbm | head
    % to find the length of the header and read that length
    % into the buffer and discard, leaving only samples.
    infile buf 0 16#5d getinterval readhexstring pop pop 
    
    320 215 1
    [ 1 0 0 -1 0 215 ]
    { infile buf readhexstring pop } image
    
    showpage
    

    The spacewar.asc is the same ugly block of bare hex samples.

    $ head spacewar.asc
    50340a2346696c6520736f757263653a20687474703a2f2f636f6d6d6f6e
    732e77696b696d656469612e6f72672f77696b692f46696c653a53706163
    65776172212d5044502d312d32303037303531322e6a70670a3332302032
    31350a007fffffffffffffffffffffffffffffffffffffffffffffffffff
    ffffffffffffffffffffffffff007fffffffffffffffffffffffdfffffff
    ffffffffffffffffffffffffffffffffffffffffffffff007fffffffffff
    ffffffffffff803fffffffffffffffffffffffffffffffffffffffffffff
    ffffff007ffffffffffffffffffffffff800ffffffffffffffffffffffff
    ffffffffffffffffffffffffff007fffffffffffffffffffffff7fe007ff
    ffffffffffffffffffffffffffffffffffffffffffffff007fffffffffff
    

    This block of samples can be left external, so long as the interpreter (or distiller) does not have the SAFER option set, as this disables the file-access operators.

    It can also be inlined after the image call by using currentfile as above.

    %!
    /buf 256 string def
    
    320 215 1
    [ 1 0 0 -1 0 215 ]
    { currentfile buf readhexstring pop }
    { 
        infile buf 0 16#5d getinterval readhexstring pop pop  % discard header
        image 
    } exec
    50340a2346696c6520736f757263653a20687474703a2f2f636f6d6d6f6e
    732e77696b696d656469612e6f72672f77696b692f46696c653a53706163
    65776172212d5044502d312d32303037303531322e6a70670a3332302032
    31350a007fffffffffffffffffffffffffffffffffffffffffffffffffff
    ffffffffffffffffffffffffff007fffffffffffffffffffffffdfffffff
    ffffffffffffffffffffffffffffffffffffffffffffff007fffffffffff
    ffffffffffff803fffffffffffffffffffffffffffffffffffffffffffff
    ffffff007ffffffffffffffffffffffff800ffffffffffffffffffffffff
    ffffffffffffffffffffffffff007fffffffffffffffffffffff7fe007ff
    ffffffffffffffffffffffffffffffffffffffffffffff007fffffffffff
    %...
    

    Or, so long as the data is less than 64k, you can slurp it into a string. [ Note: this is a historical implementation limitation on the size of strings. I have been informed that current versions of ghostscript can handle larger strings just fine. ] This is useful if you want to re-use the image several times in a document.

    %!
    /imgbuf 320 215 mul 8 div ceiling cvi string def   % create a string for byte storage (<64k)
    
    { 
        currentfile imgbuf 0 16#5d getinterval readhexstring pop pop  % read header
        currentfile imgbuf readhexstring pop pop                 % read data (discarding header data)
    } exec
    50340a2346696c6520736f757263653a20687474703a2f2f636f6d6d6f6e
    732e77696b696d656469612e6f72672f77696b692f46696c653a53706163
    65776172212d5044502d312d32303037303531322e6a70670a3332302032
    31350a007fffffffffffffffffffffffffffffffffffffffffffffffffff
    ffffffffffffffffffffffffff007fffffffffffffffffffffffdfffffff
    ffffffffffffffffffffffffffffffffffffffffffffff007fffffffffff
    ffffffffffff803fffffffffffffffffffffffffffffffffffffffffffff
    ffffff007ffffffffffffffffffffffff800ffffffffffffffffffffffff
    ffffffffffffffffffffffffff007fffffffffffffffffffffff7fe007ff
    ffffffffffffffffffffffffffffffffffffffffffffff007fffffffffff
    %...
    
    320 215 1
    [ 1 0 0 -1 0 215 ]
    { imgbuf }
    image
    

    The bit I glossed over earlier (the matrix argument)...

    In all of the above code, I'm taking a great liberty in the interpretation of PLRM. Basically ignoring some common advice, because it usually (in my experience) just gets in the way of understanding the process, but here it is...

    The recommended method for using the image operator is to use a different kind of matrix than that shown above. The matrix is actually interpreted by the image operator as an inverse map. That is, to scale up you make the numbers smaller, and to scale down you make the numbers bigger. The way you're intended to use it is (modifying the final example above, because it's the shortest and well-factored for this example, ie. assume imgbuf has been populated as above with readhexstring). This call should more properly be written:

    320 215 scale  % scale 1x1 image to proper dimensions
    320 215 1          % "data" dimensions: w h bit-depth
    [ 320 0 0 -215 0 215 ]              % inverse mapping
    { imgbuf }   % data-acquisition (yield data in a string)
    image
    

    That is, the matrix inverts (here, a poetic sense of "twisting-up", not the technical sense) the image into a 1-unit-X-1-unit square, which allows (requires) you to scale the coordinate-system to get a 1pt-per-pixel rendering of the image. The proper approach affords you more flexibility: you now have the 320 215 scale line to make sensible scaling calculations with -- at the expense of repeating yourself if you just want a 1pixel-to-1point mapping.

    To double the dimensions of the image with the proper code, it's a simple matter of replacing 320 215 scale with 640 430 scale (or adding a 2 2 scale).

    320 215 scale
    2 2 scale % == 640 430 scale
    320 215 1                           % w h bit-depth
    [ 320 0 0 -215 0 215 ]              % inverse mapping
    { imgbuf }   % data-acquisition
    image
    

    But with the hackish way, you actually have to halve the matrix to get the inverse of growth. :D

    320 215 1
    [ .5 0 0 -.5 0 430 ] % "doubled,inverted (ie. halved) with double-offset" matrix
    { imgbuf }
    image
    
    0 讨论(0)
  • 2020-12-10 08:59

    See the PostScript Language Reference Manual, this is not a trivial subject and you will need to read carefully. Start with Section 4.10 and read at least the sections dealing with type 1 images (4.10.1 to 4.10.5).

    Here is a simple example:

    /OneComponentString <007ff700> def
    
    /OneComponentImage1
    {
    <<
    /ImageType 1
    /Width 2
    /Height 2
    /ImageMatrix [2 0 0 -2 0 2]
    /BitsPerComponent 8
    /Decode [0 1]
    /DataSource OneComponentString
    >>
    } bind def
    
    gsave
    0 0 moveto
    20 20 scale
    /DeviceGray setcolorspace
    OneComponentImage1 image
    grestore
    
    showpage
    
    0 讨论(0)
提交回复
热议问题