12

The pdfinlimg package and perl script allow to include ("binary") images directly into the LaTeX source code via the \pdfliteral command.

For example,

\documentclass[margin=1cm]{standalone}
\newcommand{\pdfinlimg}[5]{
\makebox[#1cm][l]{\immediate\pdfliteral{
  q
  #3 0 0 #4 0 0 cm
  #1 0 0 #2 0 0 cm
  0.885 0 0 0.885 0 0 cm
  BI
  /W #3
  /H #4
  /CS /RGB
  /BPC 8
  /F [ /AHx /Fl ]
  ID
  #5>
  EI
  Q
}\vbox to #2cm{}}
}

\begin{document}
\pdfinlimg{1}{1}{48}{48}{
789CED973D68625918866108290649B1488A41A658C216214C112E1641A6182445901483A40821C5
202982A4089222488A202944528858C8C562902D06994AA6089262B8A4089262902D069962912D16
AB45B60887619F73BFEBF1EAD59098728597C3F5CBF979CFFBFD9DA89F4ACD31C71C73CCF10834BE
344AC552E1B200F4477EF0F1740BA87FAA3F878C73E3A43EA4621BB1D886158B5A56D41A7E449F6C
09FF125E7BB3363BA57B95D84AC4DEC632C719F5A3AEBE3F0F7FD4ACD59585170BE1E570E77B6736
3E28933B4FF76E6D05EE6C75D554D5BE878FBDE1F7448BFC6464D59DDEA1FB25175F8FA0925DB1D9
7C363E858BB4ECA6B7FDD45115A5CA4A8FE6E3B4A34E3A9E25DF53C7ED91BF0256B1F6D6EEDF9412
EB91D05268463E3F7D7C00373547F8F1BEA9B61A1E01C86CD6C70903D6DE797CD0A7542ECDEC2FCD
E7BAE16D7BD456515B15FBDE4113E90561265FD59FE52FA3CFD7A6B7E1454F1DB6C7AF5F1EA0A272
DB39EBB5055AA72D6D292AB5EFE85532FFAA9E7CBB46489371C9F7C9C4768231BE197F6CC605F5A9
041CE143E3A891DA4AE9045FB720D63C6E6A3EBB4D75D6F5E65F37D23B71E267E5B71532776F778F
117A7C3C32E346F409467265A80C401676263670075522114D74CE3B23CCAF1B99DDF8C2E2C2CAAF
2B9993945DB5D38769F82054FB5BFBC9FA4C2443F4CAF5CB1E1FC808A5F4513AB214198934978FC4
331300C556F3D94AB4EE5A7228ED207D90C66EC09EF5CFF5117D82FE3247104E83F0F0EB03E80EEC
1C5F8D0F11B5F676925457E10C5207A9317D58C5A1125D1AAE43DD3298E34FF177F1D2656618CF02
04294E889F317D18D98106B1B6AA417166C44186B0D6C7E5C371B5DF6B860F4B186B1F6B8039126F
181909033B9F19D1073E1BB6A634965F017DFCE7FA49FA476E0D1F89A8EE9F5DCD275FD096170B22
88804843551C0DB7EC41425757FFE9F9FE4894EE3BAD8DC2DA2B7D77BDD6C7C49C1B2469FE943DCB
465EBB45A96AC3874022F038578C1ACB61BEF1D4DEFE5EE86528FB21E1E9435338EF8DC74F591749
67B3C48DB2A759EFA0AACDC38020445EF9392257D5EEFCE8401E674998455E0DF900729F0285D100
01F135E1C487E623FABCABEB62E2CFF1814ACE89039FCC49C69CDBBC6EF2EC9156E5970277702E22
705F2AA1F04101A0F90C8A76FF9FBE0E9EAA2D23C1234ED4B73E480CF37D62CA0FF8A08F5183EB60
818F3F60B0247792B98B9CEC6CF88CE91344EBB6C565C97D1C5738F7E5BB3F6C0869DAA8DBCB8C3E
AD8ADD75513ACB12817EC50016C8F053FE54BFC831B37359B0449FCA543EA0F7770F2FE3475D7F6E
EADE4B83483EED7842114B7476F8F8F469B3A78B46C52641A81E42061ABA74B8DF5246F05DCB9DD9
E7A7F1D7E3DF1BB7EE7BE358FAFB7855A47B528AC90BA758EA974B7D970F118BBF600519E90B7C00
68F34D30EBC915DB394A5B4B21CF5F0F37FDFBD1F7CF4D4D7D76C693BD32DEBF4C3A43CF04611092
5C784D7E3E103FF0E73AEC061036B91DCF1D26953C59A144AE114E8C01348B99D44E5C97D04171E6
D06920D1886D04D4CF8F758BDA328D0FC985DF054C238428F54E256350CFA74A47F18988BDD199C2
AD75C41E67389124A219713589613EF49BC74D76620632A40CAA36AF9A529F83A04D20110D45DA07
0B1F90FDB958D47D81B3C89D6961031F2E423523F6206FD6A295DC4E1E78682E35D63F5AEE638CDC
61A6143124C2825D1B0FD3BA07BD0C89CB242AF06CFFDFFE03614C6B932ACD5AF977098B1616CB72
588C08AE15FEAB0BA80CE643773DB7DD30997399C989B8438CDA418B5E91344BC0C3394E6995022E
BD0C7F2117948C8591D0A24305D722BE9C6B66C21029FC46B67AD27B1EF5A46B18F058C2BF7E8B18
272E77BE3A6333694688E9B798F7DED310BCC2FD14FBB4B5F7B32E9F638E39E6F8DFE33FDD12CF75
}
\end{document}

produces

Nyan cat

via pdflatex.

Is something similar possible with PDF files instead of raster images, i.e. can I copy the (somehow encoded) PDF source code into my LaTeX file such that it is embedded like it would be if I used \includegraphicswith a regular file?

EDIT: Consider the following simple and uncompressed PDF

%PDF-1.4
%¿÷¢þ
1 0 obj
<< /Pages 3 0 R /Type /Catalog >>
endobj
2 0 obj
<< /Creator (cairo 1.10.2 \(http://cairographics.org\)) /Producer (cairo 1.10.2 \(http://cairographics.org\)) >>
endobj
3 0 obj
<< /Count 1 /Kids [ 4 0 R ] /Type /Pages >>
endobj
4 0 obj
<< /Contents 5 0 R /Group << /CS /DeviceRGB /S /Transparency /Type /Group >> /MediaBox [ 0 0 32.078125 30.984375 ] /Parent 3 0 R /Resources 6 0 R /Type /Page >>
endobj
5 0 obj
<< /Length 69 >>
stream
q
Q q
q
1 0 0 1 -0.000000000000000184 -0.015625 cm
/a0 gs /x5 Do
Q
Q
endstream
endobj
6 0 obj
<< /ExtGState << /a0 << /CA 1 /ca 1 >> >> /XObject << /x5 7 0 R >> >>
endobj
7 0 obj
<< /BBox [ 0 0 33 31 ] /Group << /CS /DeviceRGB /S /Transparency /Type /Group >> /Resources 8 0 R /Subtype /Form /Type /XObject /Length 590 >>
stream
q
0 0 0 rg /a0 gs
28.938 30.203 m 16.031 7.781 l 3.141 30.203 l 2.828 30.656 2.234 31 
1.641 31 c 0.844 31 0 30.406 0 29.547 c 0 1.516 l 0 0.656 0.734 0.016 
1.641 0.016 c 2.578 0.016 3.281 0.656 3.281 1.516 c 3.281 23.375 l 
7.062 16.844 10.797 10.328 14.547 3.797 c 14.797 3.297 15.391 3 16.031 
3 c 16.734 3 17.125 3.406 17.531 3.797 c 21.266 10.328 25 16.844 28.781 
23.375 c 28.781 1.516 l 28.781 0.656 29.484 0.016 30.438 0.016 c 31.328 
0.016 32.078 0.656 32.078 1.516 c 32.078 29.5 l 32.078 30.344 31.234 31 
30.438 31 c 29.828 31 29.234 30.75 28.938 30.203 c h
28.938 30.203 m f
Q
endstream
endobj
8 0 obj
<< /ExtGState << /a0 << /CA 1 /ca 1 >> >> >>
endobj
xref
0 9
0000000000 65535 f 
0000000015 00000 n 
0000000064 00000 n 
0000000192 00000 n 
0000000251 00000 n 
0000000427 00000 n 
0000000545 00000 n 
0000000630 00000 n 
0000001395 00000 n 
trailer << /Info 2 0 R /Root 1 0 R /Size 9 /ID [<28d7524294bb60d1f3e318954d8f7b36><28d7524294bb60d1f3e318954d8f7b36>] >>
startxref
1455
%%EOF

showing the letter M of the METAPOST logo:

enter image description here

How could I include the drawing instructions into my LaTeX code?

  • Principally yes. You can copy the content stream between stream ... endstream of a PDF page object. But be aware that the content may depend on resources which are stored as additional PDF objects. They would need to be re-created in your document. The dependencies are listed in the \Resources dictionary of the page object. – AlexG Apr 29 '14 at 15:25
  • How would I do that in practice? – porst17 Apr 29 '14 at 15:28
10

The method in the question uses inline images. If the same image is used several times, then it is embedded each time increasing the file size. Thus this method is not recommended for larger images that are used more than once. The PDF specification says:

8.9.7 Inline Images

As an alternative to the image XObjects described in Section 8.9.5, "Image Dictionaries," a sampled image may be specified in the form of an inline image. This type of image is defined directly within the content stream in which it will be painted rather than as a separate object. Because the inline format gives the application less flexibility in managing the image data, it should be used only for small images (4 KB or less).

Arbitrary PDF files cannot be inlined:

  • Fonts needs to be defined, included, and declared in the page resources. The names must not conflict with existing names.
  • The same problem arises for other resources (graphical state, ...).

Thus the easiest way is using \pdfximage.

There is a small exception, if the PDF contents stream only contains some simple drawing instructions. These can be embedded via \pdfliteral (see TikZ drawing operators). But the stuff should be put inside a save/restore pair (q ... Q), because the reference point and current transfer matrix must not be changed; pdfTeX does not analyze the PDF page stream operators in \pdfliteral and will get confused.

The program pdftk (and some others) can uncompress PDF files:

pdftk test.pdf cat output test-uncompress.pdf uncompress

Then you have to look for the page object. It can be found on the following path:

File trailer at the end of the file, e.g.:

trailer

<<
/Info 6 0 R
/Root 5 0 R
/Size 7
/ID [<7f98aa3833c5442f9b261368ace2d575> <7f98aa3833c5442f9b261368ace2d575>]
>>
startxref
810
%%EOF

The entry Root links to the Catalog object 5:

5 0 obj 
<<
/Pages 3 0 R
/Type /Catalog
>>
endobj 

The Pages entry:

2 0 obj 
<< 
/Parent 3 0 R 
/MediaBox [0 0 595.276 841.89] 
/Resources 1 0 R
/pdftk_PageNum 1
/Contents 4 0 R
/Type /Page
>>
endobj 

Pages is the root for the page tree:

3 0 obj 
<<
/Kids [2 0 R]
/Count 1
/Type /Pages
>>
endobj 

And we get object 2 as page object:

2 0 obj 
<<
/Parent 3 0 R
/MediaBox [0 0 595.276 841.89]
/Resources 1 0 R
/pdftk_PageNum 1
/Contents 4 0 R
/Type /Page
>>
endobj 

Now we have the page stream object as value for Contents, object 4:

4 0 obj 
<<
/Length 201
>>
stream
q
1 0 0 1 149.21 660.395 cm
[]0 d 0 J 0.996 w 0 0 m 0 56.693 l S
Q
q
1 0 0 1 149.709 660.893 cm
[]0 d 0 J 0.996 w 0 0 m 56.693 0 l S
Q
q
1 0 0 1 206.9 660.395 cm
[]0 d 0 J 0.996 w 0 0 m 0 56.693 l S
Q

endstream 
endobj 

The part between stream and endstream then goes to \pdfliteral usually surrounded by q and Q. In this special case the latter is not necessary, because the code draws three lines, each of them is already surrounded by q and Q. The drawing area is the MediaBox of the Page object:

/MediaBox [0 0 595.276 841.89]

Ghostscript's device bbox can calculate the visible bounding box:

gs -sDEVICE=bbox -dBATCH -dNOPAUSE test.pdf
...
Page 1
%%BoundingBox: 148 660 208 718
%%HiResBoundingBox: 148.712058 660.395019 207.397962 717.088056

The unit in PostScript and PDF is bp.

Then you can calculate the shifting, scaling (either using PDF operators or at TeX level using \scalebox) and the position (e.g. environment picture can help) for the \pdfliteral.

Example:

\documentclass{article}
\usepackage{graphicx}

\begin{document}
\setlength{\fboxsep}{2pt}
\setlength{\fboxrule}{.1pt}

\fbox{\includegraphics{test.mps}}

\fbox{%
  \setlength{\unitlength}{1bp}%
  \begin{picture}(58.685904,56.693037)% width and height of the image
    \put(-148.712058,-660.395019){%
      \pdfliteral{%
        q % save
          1 0 0 rg 1 0 0 RG % make it red
          % operators from the /Contents object of the PDF image:
          q
          1 0 0 1 149.21 660.395 cm
          []0 d 0 J 0.996 w 0 0 m 0 56.693 l S
          Q
          q
          1 0 0 1 149.709 660.893 cm
          []0 d 0 J 0.996 w 0 0 m 56.693 0 l S
          Q
          q
          1 0 0 1 206.9 660.395 cm
          []0 d 0 J 0.996 w 0 0 m 0 56.693 l S
          Q
        Q % restore
      }%
    }%  
  \end{picture}%
}
\end{document}

Result


Related: MPS, the output of MetaPost is a simplified PostScript that can be embedded via \pdfliteral, see the conversion macros of Hans Hagen, that are loaded by pdftex.def.

The program purifyeps can convert PostScript and PDF files to the PostScript that MetaPost outputs, e.g.:

purifyeps test.pdf test.mps

Then test.mps can be included via \includegraphics.

  • In my case, I only have a PDF with simple drawing instructions similar to the one I added to my question. Could you provide the actual code for the inclusion? The hint about METAPOST sounds interesting as well. Can it also be used with XeLaTeX and LuaLaTeX? – porst17 Apr 30 '14 at 7:31
  • 2
    The MetaPost output is PostScript, thus XeTeX can include them as PostScript images. And LuaTeX is not different than pdfTeX retarding the inclusion of MPS files. – Heiko Oberdiek Apr 30 '14 at 10:51
6

Your PDF example showing the Metapost Logo is relatively simple and can be inlined by inlining the XObject content stream with the drawing statements (Object No. 7 0) into the Page content stream. The XObject content stream references the External Graphics State (Object No 8 0) as /a0 which we inline as well:

\documentclass[margin=1cm]{standalone}

\begin{document}
\pdfliteral page {
q
0 0 0 rg /CA 1 /ca 1
28.938 30.203 m 16.031 7.781 l 3.141 30.203 l 2.828 30.656 2.234 31
1.641 31 c 0.844 31 0 30.406 0 29.547 c 0 1.516 l 0 0.656 0.734 0.016
1.641 0.016 c 2.578 0.016 3.281 0.656 3.281 1.516 c 3.281 23.375 l
7.062 16.844 10.797 10.328 14.547 3.797 c 14.797 3.297 15.391 3 16.031
3 c 16.734 3 17.125 3.406 17.531 3.797 c 21.266 10.328 25 16.844 28.781
23.375 c 28.781 1.516 l 28.781 0.656 29.484 0.016 30.438 0.016 c 31.328
0.016 32.078 0.656 32.078 1.516 c 32.078 29.5 l 32.078 30.344 31.234 31
30.438 31 c 29.828 31 29.234 30.75 28.938 30.203 c h
28.938 30.203 m f
Q
}
\end{document}
  • A pity that I cannot accept two answers at the same time. – porst17 Apr 30 '14 at 13:27
  • @porst17 No problem. – AlexG Apr 30 '14 at 13:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.