luametafun-potrace.tex /size: 7137 b    last modification: 2025-02-21 11:03
1% language=us runpath=texruns:manuals/luametafun
2
3\environment luametafun-style
4
5\startcomponent luametafun-potrace
6
7\startchapter[title={Potrace}]
8
9\startsection[title=Introduction]
10
11The potrace connection targets at bitmaps. You can think of logos that only exist
12as bitmaps while outlines are preferred, but in this case we actually think more
13of bitmaps that the user lays out. In order to give an impression what we are
14talking about I give three simple examples:
15
16\startbuffer[potraced]
1701111111111111111111111111111100
1811000000000000000000000000000110
1911000000000000000000000000000011
2011000000000000000000000000000011
2111000000000000000000000000000011
2201100000000000000000000000000011
2300111111111111111111111111111110
24\stopbuffer
25
26\savebuffer[list=potraced,file=potraced.txt,prefix=no]
27
28\startbuffer[1]
29\startMPcode
30    fill
31        lmt_potraced [ bytes =
32            "01111111111111111111111111111100
33             11000000000000000000000000000110
34             11000000000000000000000000000011
35             11000000000000000000000000000011
36             11000000000000000000000000000011
37             01100000000000000000000000000011
38             00111111111111111111111111111110",
39        ] ysized 1cm
40        withcolor "darkblue"
41        withpen pencircle scaled 1 ;
42\stopMPcode
43\stopbuffer
44
45\startbuffer[2]
46\startMPcode
47    fill
48        lmt_potraced [
49            filename = "potraced.txt",
50        ] ysized 1cm
51        withcolor "darkgreen"
52        withpen pencircle scaled 1 ;
53\stopMPcode
54\stopbuffer
55
56\startbuffer[3]
57\startMPcode
58    fill
59        lmt_potraced [
60            buffer = "potraced",
61        ] ysized 1cm
62        withcolor "darkred"
63        withpen pencircle scaled 1 ;
64\stopMPcode
65\stopbuffer
66
67\startlinecorrection
68\startcombination[nx=3,ny=1]
69    {\getbuffer[1]} {\type {bytes}}
70    {\getbuffer[2]} {\type {buffer}}
71    {\getbuffer[3]} {\type {filename}}
72\stopcombination
73\stoplinecorrection
74
75Here we vectorize bitmaps with Peter Selingers potrace library, that we built in
76\LUAMETATEX. We can directly feed bytes in a \METAFUN\ blob:
77
78\typebuffer[1][option=TEX]
79
80But we can also go via a file that has the same data:
81
82\typebuffer[2][option=TEX]
83
84Of course we can also use buffers:
85
86\typebuffer[3][option=TEX]
87
88You feed a bitmap specification and get back a \METAPOST\ path, likely multiple
89subpaths sewed together. You can of course draw and fill that path, or store it
90in a path variable and then do both.
91
92In the following sections we will explore the various options and some tricks.
93The main message in this section is that you need to look at bitmaps with
94vectorized eyes because that is what you get in the end: a vector representation.
95
96\stopsection
97
98\startsection[title=Functions]
99
100{\em todo}
101
102\stopsection
103
104\startsection[title=Icons]
105
106When Mikael Sundqvist and I were playing with potrace in \METAFUN\ his girls came
107up with this pattern.
108
109\startbuffer
110\startMPcode
111fill
112    lmt_potraced [ bytes =
113        "001111100
114         010000010
115         100000001
116         101101101
117         100000001
118         101000101
119         100111001
120         010000010
121         001111100",
122         size = 1,
123    ] xysized (3cm,3cm)
124    withcolor "middleorange" ;
125\stopMPcode
126\stopbuffer
127
128\typebuffer[option=TEX]
129
130This produces the following icon. The somewhat asymmetrical shape gives it a
131charm, and it is surprising how little code is needed. This picture inspired
132Willi Egger to make a ten by ten composition gadget for the attendants of the
1332023 \CONTEXT\ meeting that was used in a tutorial.
134
135\startlinecorrection \getbuffer \stoplinecorrection
136
137We use this to demonstrate a few more features of the interface:
138
139\startbuffer
140\startMPcode
141draw
142    lmt_potraced [ bytes =
143        "..11111..
144         .1.....1.
145         1.......1
146         1.11.11.1
147         1.......1
148         1.1...1.1
149         1..111..1
150         .1.....1.
151         ..11111..",
152         polygon = true,
153         size = 1,
154    ] xysized (3cm,3cm)
155    withcolor "darkblue"
156    withpen pencircle scaled 1mm ;
157\stopMPcode
158\stopbuffer
159
160\typebuffer[option=TEX]
161
162This contour is actually accurate:
163
164\startlinecorrection \getbuffer \stoplinecorrection
165
166We can color some components:
167
168\startbuffer
169\startMPcode
170draw image (
171    lmt_startpotraced [ bytes =
172        "..11111..
173         .1.....1.
174         1.......1
175         1.22.22.1
176         1.......1
177         1.3...3.1
178         1..333..1
179         .1.....1.
180         ..11111.."
181    ] ;
182    fill lmt_potraced [ value = "1", size = 1 ]
183        withcolor "darkred" ;
184    fill lmt_potraced [ value = "3", size = 1 ]
185        withcolor "darkgreen" ;
186    fill lmt_potraced [ value = "2", size = 0 ]
187        withcolor "darkblue" ;
188    lmt_stoppotraced ;
189) xysized (3cm,3cm) ;
190\stopMPcode
191\stopbuffer
192
193\typebuffer[option=TEX]
194
195Of course there must be enough distinction (white space) between the
196shapes:
197
198\startlinecorrection \getbuffer \stoplinecorrection
199
200Again we show the polygons:
201
202\startbuffer
203\startMPcode
204draw image (
205    lmt_startpotraced [ bytes =
206        "..11111..
207         .1.....1.
208         1.......1
209         1.22.22.1
210         1.......1
211         1.3...3.1
212         1..333..1
213         .1.....1.
214         ..11111.."
215    ] ;
216    draw lmt_potraced [ value = "1", size = 1, polygon = true ]
217        withcolor "darkred" ;
218    draw lmt_potraced [ value = "3", size = 1, polygon = true ]
219        withcolor "darkgreen" ;
220    draw lmt_potraced [ value = "2", size = 0, polygon = true ]
221        withcolor "darkblue" ;
222    lmt_stoppotraced ;
223)
224    xysized (3cm,3cm)
225    withpen pencircle scaled 1mm ;
226\stopMPcode
227\stopbuffer
228
229\typebuffer[option=TEX]
230
231Gives:
232
233\startlinecorrection \getbuffer \stoplinecorrection
234
235We can do the same with data defined in \LUA:
236
237\startbuffer
238\startluacode
239io.savedata("temp.txt",[[
240..11111..
241.1.....1.
2421.......1
2431.22.22.1
2441.......1
2451.3...3.1
2461..333..1
247.1.....1.
248..11111..
249]])
250\stopluacode
251\stopbuffer
252
253\typebuffer[option=TEX]
254
255With:
256
257\startbuffer
258\startMPcode
259draw image (
260    lmt_startpotraced [ filename = "temp.txt" ] ;
261        fill lmt_potraced [ value = "1", size = 1 ]
262            withcolor "darkcyan" ;
263        fill lmt_potraced [ value = "3", size = 1 ]
264            withcolor "darkmagenta" ;
265        fill lmt_potraced [ value = "2", size = 0 ]
266            withcolor "darkyellow" ;
267    lmt_stoppotraced ;
268) xysized (3cm,3cm) ;
269\stopMPcode
270\stopbuffer
271
272\typebuffer[option=TEX]
273
274Indeed we get:
275
276\startlinecorrection \getbuffer \stoplinecorrection
277
278\stopsection
279
280\startsection[title=Fonts]
281
282{\em maybe}
283
284\stopsection
285
286\stopchapter
287
288\stopcomponent
289
290
291% border case with messy end point
292
293% \enabletrackers[potrace.results]
294%
295% \starttext
296%
297% \startMPpage
298%
299%     string s ; s := "
300% 000000004444040
301% 100000000004040
302%     ";
303%
304%     path p ;
305%     p := lmt_potraced [ bytes = s, threshold=2, optimize="yes", explode="yes", value = "4" ] ;
306%
307%     fill p withpen pencircle scaled 1.5 withcolor "darkred" ;
308%     draw p withpen pencircle scaled 1.5 withcolor "darkblue" ;
309%
310%     currentpicture := currentpicture xysized (100,100) ;
311%
312%     setbounds currentpicture to (boundingbox currentpicture) enlarged 200 ;
313%
314%     addbackground withcolor "darkgray" ;
315% \stopMPpage
316%
317% \stoptext
318