Как включить img в постскриптум

Я хочу добавить изображение в свой постскрипт код

%!PS-Adobe-3.0

/Times-Roman findfont
12 scalefont setfont

50 700 moveto
(text) show
showpage

но у меня нет идеи сделать это. Кто-нибудь поможет?

3 ответа

;tldr

перейдите к середине и начните чтение с упрощенного рабочего процесса до конца.

конвертировать в xbm, взломать с помощью vi, встроенные данные с помощью {currentfile} image

Это задокументировано в Справочном руководстве по языку Postscript, но эту информацию может быть немного трудно переварить.

Как говорит Кен, вам нужно использовать image оператор. Я обычно хожу на "старую школу" форму, которая

ширина высота бит на пиксель матрица proc изображение -

Для некоторого файла случайного изображения, вы обычно хотите использовать что-то вроде convert из ImageMagick, чтобы получить текстовый формат. Конечно, вы также можете просто преобразовать его в eps, но чтобы учиться, вы должны засунуть в него пальцы.

% convert image.png image.xbm

Это даст вам файл вроде:

  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   };

Итак, в vi сделайте несколько вещей, таких как

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

Давать что-то вроде этого:

  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

Затем вы используете цифры в image вызовите, обрежьте эти строки и вставьте данные непосредственно после этих строк

%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

Это предполагает, что у ваших растровых данных значение y увеличивается вниз. Этот подход может быть изменен для других форматов ascii, если вы можете получить какую-то дамп необработанных образцов. Вложение сжатых изображений с помощью кода декодера - это большая банка червей, которую я советую избегать некоторое время. (В основном потому, что я пока не знаю, как это сделать. Я избегал этого, как большой червяк.:D)


Я проверил мой совет выше, и есть большая загвоздка, которую я забыл. Постскриптум любит свои растровые изображения в байтах с прямым порядком байтов. То есть бит 7 - самый левый, а бит 0 - самый правый. Это обратная сторона формата xbm. Итак, завершенная программа, представленная выше:

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

Полная программа доступна с полными данными изображения, добавленными здесь.


Упрощенный рабочий процесс

Проще, но все же "практический", это преобразовать в pbm который использует те же правила упорядочения битов, что и postscript. затем xxd -ps создаст "постскриптум" hexdump. В следующих трех примерах используются шестнадцатеричные данные, подготовленные таким образом. Но этот метод все еще требует, чтобы вы вручную измеряли длину заголовка (используйте xxd чтобы найти смещение байта после символа пробела после ширины и высоты).

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

spacewar.asc это тот же самый уродливый блок голых шестнадцатеричных образцов.

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

Этот блок сэмплов можно оставить внешним, если в интерпретаторе (или дистилляторе) не установлена ​​опция SAFER, поскольку это отключает операторы доступа к файлу.

Он также может быть встроен после вызова изображения с помощью currentfile как указано выше.

%!
/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
%...

Или, если данные меньше 64 КБ, вы можете записать их в строку. [Примечание: это историческое ограничение реализации размера строк. Мне сообщили, что текущие версии ghostscript могут нормально обрабатывать большие строки. ] Это полезно, если вы хотите повторно использовать изображение в документе несколько раз.

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

Бит, который я замаскировал ранее (матричный аргумент)...

Во всем вышеприведенном коде я беру большую свободу в интерпретации PLRM. В основном игнорируя некоторые общие советы, потому что обычно (по моему опыту) просто мешает понять процесс, но вот он...

Рекомендуемый метод для использования image оператор должен использовать матрицу другого типа, чем та, что показана выше. Матрица фактически интерпретируется image Оператор как обратное отображение. То есть для увеличения вы уменьшаете числа, а для уменьшения - больше. То, как вы намереваетесь его использовать, - это изменение последнего примера, приведенного выше, потому что это самый короткий и хорошо продуманный пример для этого примера, т.е. imgbuf был заполнен как указано выше readhexstring). Этот вызов должен быть более правильно записан:

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

То есть матрица инвертирует (здесь поэтическое чувство "скручивания", а не технический смысл) изображение в квадрат размером 1 единица X-1, что позволяет (требует) масштабировать координату система, чтобы получить 1pt на пиксель рендеринга изображения. Правильный подход дает вам больше гибкости: теперь у вас есть 320 215 scale линия, чтобы сделать разумные вычисления масштабирования с - за счет повторения, если вы просто хотите, чтобы отображение 1 пиксель к 1 точке.

Чтобы удвоить размеры изображения с помощью правильного кода, достаточно просто заменить 320 215 scale с 640 430 scale (или добавив 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

Но с помощью хакерского способа вы фактически должны вдвое сократить матрицу, чтобы получить обратный рост.: D

320 215 1
[ .5 0 0 -.5 0 430 ] % "doubled,inverted (ie. halved) with double-offset" matrix
{ imgbuf }
image

См. Справочное руководство по языку PostScript, это не тривиальная тема, и вам нужно будет внимательно ее прочитать. Начните с Раздела 4.10 и прочитайте, по крайней мере, разделы, относящиеся к изображениям типа 1 (с 4.10.1 по 4.10.5).

Вот простой пример:

/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

Я бы предложил простой способ - запустить файл EPS.
Сначала преобразуйте изображение в EPS, напр. myimage.eps, сохраните его в myfolder, а затем измените свой код, чтобы определить оператор placeEPS и отобразить myimage.eps, используя его.

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

Теперь конвертируйте в PDF с помощью Acrobat Distiller или GhostScript.
Вы также можете использовать этот подход для размещения полностраничного холста в документе.

Другие вопросы по тегам