graphics.tex /size: 12 Kb    last modification: 2024-01-16 09:02
1% language=us runpath=texruns:manuals/graphics
2
3\usemodule[article-basic]
4\usemodule[abbreviations-smallcaps]
5\usemodule[setups-basics]
6\usemodule[scite]
7
8% \setupbodyfont
9%   [dejavu]
10
11\loadsetups[context-en]
12
13\definecolor
14  [mysetupscolora]
15  [a=1,
16   t=.25,
17   r=.5,
18   g=.5]
19
20\definecolor
21  [mysetupscolorb]
22  [a=1,
23   t=.25,
24   g=.25,
25   b=.25]
26
27\definetextbackground
28  [mysetups]
29  [before=\blank,
30   after=\blank,
31   topoffset=10pt,
32   leftoffset=10pt,
33   location=paragraph,
34   backgroundcolor=mysetupscolora,
35   backgroundcolor=mysetupscolorb,
36   frame=off]
37
38\startsetups xml:setups:start
39    \starttextbackground[mysetups]
40\stopsetups
41
42\startsetups xml:setups:stop
43    \stoptextbackground
44\stopsetups
45
46\starttext
47
48\startbuffer[image]
49    \startluacode
50
51        local min, max, random = math.min, math.max, math.random
52
53        -- kind of self-explaining:
54
55        local xsize      = 255
56        local ysize      = 255
57        local colordepth = 1
58        local usemask    = true
59        local colorspace = "rgb"
60
61        -- initialization:
62
63        local bitmap = graphics.bitmaps.new(xsize,ysize,colorspace,colordepth,usemask)
64
65        -- filling the bitmap:
66
67        local data    = bitmap.data
68        local mask    = bitmap.mask
69        local minmask = 100
70        local maxmask = 200
71
72        for i=1,ysize do
73            local d = data[i]
74            local m = mask[i]
75            for j=1,xsize do
76                d[j] = { i, max(i,j), min(i,j) }
77                m[j] = random(minmask,maxmask)
78            end
79        end
80
81        -- flushing the lot:
82
83        graphics.bitmaps.tocontext(bitmap)
84
85    \stopluacode
86\stopbuffer
87
88\definelayer
89   [page]
90   [width=\paperwidth,
91    height=\paperheight]
92
93\setlayer
94   [page]
95   {\scale
96      [width=\paperwidth]
97      {\ignorespaces
98       \getbuffer[image]%
99       \removeunwantedspaces}}
100
101\setlayer
102   [page]
103   [preset=rightbottom,
104    hoffset=10mm,
105    voffset=45mm]
106   {\scale
107      [width=.6\paperwidth]
108      {Graphics}}
109
110% \setlayer
111%    [page]
112%    [preset=righttop,
113%     hoffset=10mm,
114%     voffset=20mm]
115%    {\rotate{\scale
116%       [width=.3\paperheight]
117%       {\ConTeXt\ MkIV}}}
118
119\setlayer
120   [page]
121   [preset=rightbottom,
122    hoffset=10mm,
123    voffset=20mm]
124   {\scale
125      [width=.6\paperwidth]
126      {Hans Hagen}}
127
128\startpagemakeup
129    \flushlayer[page]
130    \vfill
131\stoppagemakeup
132
133\startsubject[title=Introduction]
134
135This manual is about integrating graphics your document. Doing this is not really
136that complex so this manual will be short. Because graphic inclusion is related
137to the backend some options will discussed. It's typical one of these manuals
138that can grow over time.
139
140\stopsubject
141
142\startsubject[title=Basic formats]
143
144In \TEX\ a graphic is not really known as graphic. The core task of the engine is
145to turn input into typeset paragraphs. By the time that happens the input has
146become a linked list of so called nodes: glyphs, kerns, glue, rules, boxes and a
147couple of more items. But, when doing the job, \TEX\ is only interested in
148dimensions.
149
150In traditional \TEX\ an image inclusion happens via the extension primitive \type
151{\special}, so you can think of something:
152
153\starttyping
154\vbox to 10cm {%
155  \hbox to 4cm {%
156    \special{image foo.png width 4cm height 10cm}%
157    \hss
158  }%
159}
160\stoptyping
161
162When typesetting \TEX\ sees a box and uses its dimensions. It doesn't care what
163is inside. The special itself is just a so called whatsit that is not
164interpreted. When the page is eventually shipped out, the \DVI|-|to|-|whatever
165driver interprets the special's content and embeds the image.
166
167It will be clear that this will only work correctly when the image dimensions are
168communicated. That can happen in real dimensions, but using scale factors is also
169a variant. In the latter case one has to somehow determine the original dimensions
170in order to calculate the scale factor. When you embed \EPS\ images, which is the
171usual case in for instance \DVIPS, you can use \TEX\ macros to figure out the
172(high res) boundingbox, but for bitmaps that often meant that some external
173program had to do the analysis.
174
175It sounds complex but in practice this was all quite doable. I say \quote {was}
176because nowadays most \TEX\ users use an engine like \PDFTEX\ that doesn't need
177an external program for generating the final output format. As a consequence it
178has built-in support for analyzing and including images. There are additional
179primitives that analyze the image and additional ones that inject them.
180
181\starttyping
182\pdfximage
183  {foo.png}%
184\pdfrefximage
185  \pdflastximage
186  width 4cm
187  height 10cm
188\relax
189\stoptyping
190
191A difference with traditional \TEX\ is that one doesn't need to wrap them into a
192box. This is easier on the user (not that it matters much as often a macro
193package hides this) but complicates the engine because suddenly it has to check a
194so called extension whatsit node (representing the image) for dimensions.
195
196Therefore in \LUATEX\ this model has been replaced by one where an image
197internally is a special kind of rule, which in turn means that the code for
198checking the whatsit could go away as rules are already taken into account. The
199same is true for reuseable boxes (xforms in \PDF\ speak).
200
201\starttyping
202\useimageresource
203  {foo.png}%
204\saveimageresource
205  \lastsavedimageresourceindex
206  width 4cm
207  height 10cm
208\relax
209\stoptyping
210
211While \DVIPS\ supported \EPS\ images, \PDFTEX\ and \LUATEX\ natively support
212\PNG, \JPG\ en \PDF\ inclusion. The easiest to support is \JPG\ because the PDF\
213format supports so called \JPG\ compression in its full form. The engine only has
214to pass the image blob plus a bit of extra information. Analyzing the file for
215resolution, dimensions and colorspace is relative easy: consult some tables that
216have this info and store it. No special libraries are needed for this kind of
217graphics.
218
219A bit more work is needed for \PDF\ images. A \PDF\ file is a collection of
220(possibly compressed) objects. These objects can themselves refer to other
221objects so basically we we have a tree of objects. This means that when we embed
222a page from a \PDF\ file, we start with embedding the (content stream of the)
223page object and then embed all the objects it refers to, which is a recursive
224process because those objects themselves can refer to objects. In the process we
225keep track of which objects are copied so that when we include another page we
226don't copy duplicates.
227
228A dedicated library is used for opening the file, and looking for objects that
229tell us the dimensions and fetching objects that we need to embed. In \PDFTEX\
230the poppler library is used, but in \LUATEX\ we have switched to pplib which is
231specially made for this engine (by Pawel Jackowski) as a consequence of some
232interchange that we had at the 2018 Bacho\TEX\ meeting. This change of library
233gives us a greater independency and a much smaller code base. After all, we only
234need access to \PDF\ files and its objects.
235
236One can naively think that \PNG\ inclusion is as easy as \JPG\ inclusion because
237\PDF\ supports \PNG\ compression. Well, this is indeed true, but it only supports
238so called \PNG\ filter based compression. The image blob in a \PNG\ file
239describes pixels in rows and columns where each row has a filter byte telling how
240that row is to be interpreted. Pixel information can be derived from preceding
241pixels, pixels above it, or a combination. Also some averaging can come into
242play. This way repetitive information can (for instance) become for instance a
243sequence of zeros because no change in pixel values took place. And such a
244sequence can be compressed very well which is why the whole blob is compressed
245with zlib.
246
247In \PDF\ zlib compression can be applied to object streams so that bit is
248covered. In addition a stream can be \PNG\ compressed, which means that it can
249have filter bytes that need to be interpreted. But the \PNG\ can do more: the
250image blob is actual split in chunks that need to be assembled. The image
251information can be interlaced which means that the whole comes in 7~seperate
252chunks thet get overlayed in increasing accuracy. Then there can be an image mask
253part of the blob and that mask needs to be separated in \PDF\ (think of
254transparency). Pixels can refer to a palette (grayscale or color) and pixels can
255be codes in~1, 2, 4, 8 or 16~bits where color images can have 3~bytes. When
256multiple pixels are packed into one byte they need to be expanded.
257
258This all means that embedding \PNG\ file can demand a conversion and when you
259have to do that each run, it has a performance hit. Normally, in a print driven
260workflow, one will have straightforward \PNG\ images: 1 byte or 3 bytes which no
261mask and not interlaced. These can be transferred directly to the \PDF\ file. In
262all other cases it probably makes sense to convert the images beforehand (to
263simple \PNG\ or just \PDF).
264
265So, to summarize the above: a modern \TEX\ engine supports image inclusion
266natively but for \PNG\ images you might need to convert them beforehand if
267runtime matters and one has to run many times.
268
269\stopsubject
270
271\startsubject[title=Inclusion]
272
273The command to include an image is:
274
275\showsetup{externalfigure}
276
277and its related settings are:
278
279\showsetup{setupexternalfigure}
280
281So you can say:
282
283\starttyping[option=TEX]
284\externalfigure[cow.pdf][width=4cm]
285\stoptyping
286
287The suffix is optional, which means that this will also work:
288
289\starttyping[option=TEX]
290\externalfigure[cow][width=4cm]
291\stoptyping
292
293\stopsubject
294
295\startsubject[title=Defining]
296
297{\em todo}
298
299\showsetup{useexternalfigure}
300\showsetup{defineexternalfigure}
301\showsetup{registerexternalfigure}
302
303\stopsubject
304
305\startsubject[title=Analyzing]
306
307{\em todo}
308
309\showsetup{getfiguredimensions}
310
311\showsetup{figurefilename}
312\showsetup{figurefilepath}
313\showsetup{figurefiletype}
314\showsetup{figurefullname}
315\showsetup{figureheight}
316\showsetup{figurenaturalheight}
317\showsetup{figurenaturalwidth}
318\showsetup{figuresymbol}
319\showsetup{figurewidth}
320
321\showsetup{noffigurepages}
322
323\stopsubject
324
325\startsubject[title=Collections]
326
327{\em todo}
328
329\showsetup{externalfigurecollectionmaxheight}
330\showsetup{externalfigurecollectionmaxwidth}
331\showsetup{externalfigurecollectionminheight}
332\showsetup{externalfigurecollectionminwidth}
333\showsetup{externalfigurecollectionparameter}
334\showsetup{startexternalfigurecollection}
335
336\stopsubject
337
338\startsubject[title=Conversion]
339
340{\em todo}
341
342\stopsubject
343
344\startsubject[title=Figure databases]
345
346{\em todo}
347
348\showsetup{usefigurebase}
349
350\stopsubject
351
352\startsubject[title=Overlays]
353
354{\em todo}
355
356\showsetup{overlayfigure}
357\showsetup{pagefigure}
358
359\stopsubject
360
361\startsubject[title=Scaling]
362
363Images are normally scaled proportionally but if needed you can give an
364explicit height and width. The \type {\scale} command shares this property
365and can be used to scale in the same way as \type {\externalfigure}. I will
366illustrate this with an example.
367
368You can define your own bitmaps, like I did with the cover of this manual:
369
370\typebuffer[image][option=LUA]
371
372The actually inclusion of this image happened with:
373
374\starttyping[option=TEX]
375\scale
376  [width=\paperwidth]
377  {\getbuffer[image]}
378\stoptyping
379
380\stopsubject
381
382% \startsubject[title=The backend]
383%
384% Traditionally \TEX\ sees an image as just a box with dimensions and in \LUATEX\
385% it is actually a special kind of rule that carries information about what to
386% inject in the final (\PDF) file. In regular \LUATEX\ the core formats \type
387% {pdf}, \type {png}, \type {jpg} and \type {jp2} are dealt with by the backend but
388% in \CONTEXT\ we can use \LUA\ instead. We might default to that method at some
389% point but for now you need to enable that explicitly:
390%
391% \starttyping[option=TEX]
392% \enabledirectrive[graphics.pdf.uselua]
393% \enabledirectrive[graphics.jpg.uselua]
394% \enabledirectrive[graphics.jp2.uselua]
395% \enabledirectrive[graphics.png.uselua]
396% \stoptyping
397%
398% All four can be enabled with:
399%
400% \starttyping[option=TEX]
401% \enabledirectrive[graphics.uselua]
402% \stoptyping
403%
404% Performance|-|wise only \PNG\ inclusion can be less efficient, but only when you
405% use interlaced images or large images with masks. It makes no real sense in a
406% professional workflow to use the (larger) interlaced images, and masks are seldom
407% used at high resolutions, so in practice one will not really notice loss of
408% performance.
409%
410% The advantage of this method is that we can provide more options, intercept bad
411% images that make the backend abort and lessen the dependency on libraries.
412%
413% \stopsubject
414
415\stoptext
416