-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCore_Image.html
More file actions
380 lines (358 loc) · 113 KB
/
Copy pathCore_Image.html
File metadata and controls
380 lines (358 loc) · 113 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
<html>
<head>
<title>NodeBox | Core Image</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="imagetoolbar" content="no" />
<meta name="description" content="" />
<meta name="keywords" content="NodeBox, Core Image" />
<link rel="canonical" href="https://www.nodebox.net/code/Core_Image" />
<link type="text/css" rel="stylesheet" media="screen" href="/media/css/nbar.css">
<script type="text/javascript" src="/code/js/pop.js"></script>
<script type="text/javascript" src="/code/js/confirm.js"></script>
<link href="/code/css/default.css" rel="stylesheet" type="text/css" />
<link href="/code/css/print.css" rel="stylesheet" type="text/css" media="print" />
</head>
<body id="body">
<div class="nbar">
<ol>
<li><a class="node" href="/code/Home">NodeBox 1<span class="nbar-arrow"></span></a>
<ol class="nbar-dropdown">
<li><a href="/">Homepage</a></li>
<li><a href="/node/">NodeBox 3<small>Node-based app for generative design and data visualization</small></a></li>
<li><a href="/opengl/">NodeBox OpenGL<small>Hardware-accelerated cross-platform graphics library</small></a></li>
<li><a href="/code/Home">NodeBox 1<small>Generate 2D visuals using Python code (Mac OS X only)</small></a></li>
</ol>
</li>
<li><a class="gallery" href="/gallery/">Gallery</a></li>
<li><a class="documentation" href="/code/Tutorial">Documentation</a></li>
<li><a class="forum" href="http://support.nodebox.net/discussions">Forum</a></li>
<li><a class="blog" href="/blog/">Blog</a></li>
</ol>
</div>
<div id="all">
<div id="header_and_navigation">
<div id="header">
<a href="/code/Home"><img id="header_image" src="/code/g/header-small.jpg" width="800" /></a></div>
<div id="title">
<a href="/code/Home"><h1>NodeBox</h1>
<strong><em>Create visual output with Python programming code</em></strong>
</a></div>
<div id="contextual">
<div id="languages">
</div>
<div id="search">
<form id="sf" method="get">
<input type="text" id="q" name="q" value="" />
<a href="javascript:document.getElementById('sf').submit();">GO</a>
</form>
</div>
</div>
<div id="navigation">
<div id="navigation_public">
<a href="/code/Home">Home</a>
<a href="/code/Download">Download</a>
<a href="/code/Reference">Reference</a>
<a href="/code/Tutorial">Tutorial</a>
<a href="/code/Library">Library</a>
<a href="/code/Gallery">Gallery</a>
<a href="/code/About">About</a>
</div>
</div>
</div>
<div id="content">
<div id="nodebox-link">
<a href="/code/Home"><img src="/code/g/transparent.gif" /></a>
</div>
<div class="inside">
<h3>Core Image</h3>
<h2>Description</h2> <p>The Core Image library for NodeBox adds image manipulation to NodeBox. It's like having control over Photoshop through simple Python programming commands. <a href="http://www.apple.com/macosx/features/coreimage/">Core Image</a> is a Mac OS X specific framework available from Mac OS X 1.4 (Tiger) and up (Leopard, ...). Core Image uses hardware acceleration whenever possible. You can apply filters and transformations to images with a real-time and interactive response. And, since all of the image manipulations are stored in a script, the process is <i>non-destructive</i>. The source images remain unchanged. The script is a recipe you can reuse on different source images.</p> <h2>Download</h2> <table border="0"><tbody><tr><td><a href="https://nodebox.s3.amazonaws.com/code/data/media/coreimage.zip" target="_self"><img src="/code/data/media/download.gif" alt="download" /></a></td><td><a href="https://nodebox.s3.amazonaws.com/code/data/media/coreimage.zip">coreimage.zip</a> (1.4MB) <br /> <i>Last updated for NodeBox 1.9.5<br />Licensed under GPL<br /></i><i>Author: Tom De Smedt</i><br /></td></tr></tbody></table> <h2>Documentation</h2> <ul> <li><a href="Core_Image.html#loading_the_library" target="_self">How to get the library up and running</a></li> <li><a href="Core_Image.html#creating_a_canvas">Creating a new canvas</a></li> <li><a href="Core_Image.html#adding_layers">Adding new layers to the canvas</a></li> <li><a href="Core_Image.html#arranging_layers">Retrieving and arranging layers</a></li> <li><a href="Core_Image.html#transforming_layers">Moving and transforming layers</a></li> <li><a href="Core_Image.html#layers_adjustments">Adjusting layer brightness, contrast and saturation</a></li> <li><a href="Core_Image.html#blend_modes">Layer opacity and blending modes</a></li> <li><a href="Core_Image.html#alpha_masks">Applying alpha masks</a></li> <li><a href="Core_Image.html#filters">Layer filters</a></li><li><a href="Core_Image.html#dropshadows" target="_self">Layer dropshadows</a><br /></li> <li><a href="Core_Image.html#pixels">Working with layer pixels</a></li> <li><a href="Core_Image.html#export_the_canvas">Exporting the canvas to JPEG, GIF, PNG or TIFF</a></li> <li><a href="Core_Image.html#drawing_the_canvas">Drawing the canvas in NodeBox</a></li> <li><a href="Core_Image.html#helpers">Working with helpers and interfaces</a></li> <li><a href="Core_Image.html#morguefile">Working with images from MorgueFile</a></li><li><a href="Core_Image.html#dynamics" target="_self">Working with dynamics and caching</a><br /></li> <li><a href="Core_Image.html#issues">Known issues and limitations</a><br /></li> </ul> <p> </p> <hr /> <h2><a name="loading_the_library" title="loading_the_library"></a>How to get the library up and running</h2> <p>Put the <i>coreimage</i> library folder in the same folder as your script so NodeBox can find the library. It takes some time to load the library the first time.</p> <pre class="python">coreimage = <span style="color: #530035;">ximport</span><span style="">(</span><span style="color: #ff0080;">"coreimage"</span><span style="">)</span></pre></pre> <p> </p> <hr /> <h2><a name="creating_a_canvas" title="creating_a_canvas"></a>Creating a new canvas</h2> <p>The <i>canvas()</i> command returns a new, empty canvas. It takes two parameters: the <i>width</i> and <i>height</i> of the canvas. You can set an optional <i>quality</i> parameter to "high" to use 128-bit pixel depth but this is unnecessary in most cases. </p> <pre class="python">canvas = coreimage.<span style="">canvas</span><span style="">(</span><span style="">150</span>, <span style="">150</span><span style="">)</span></pre></pre> <p> </p> <hr /> <h2><a name="adding_layers" title="adding_layers"></a>Adding new layers to the canvas</h2> <p>A canvas is a container of many layers which you can position, scale , rotate, blend, filter, etc. You can create layers from image files, fill colors, linear or radial gradients, paths (ovals, text, ...), lists of pixels colors, another layer or canvas (i.e. a group of layers), or Quicktime movie frames.</p><p> </p><p><span class="grey_box">canvas.append()</span> </p><p>The <i>canvas.append()</i> method adds a new layer to the top of the canvas. It is placed at the center of the canvas by default. </p><pre class="python">canvas.<span style="">append</span><span style="">(</span>filename<span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span>clr<span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span>clr1, clr2, <span style="">type</span>=<span style="color: #ff0080;">"linear"</span>, spread=<span style="">0.0</span><span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span>path, <span style="color: #530035;">background</span>=<span style="color: #530035;">None</span>, <span style="color: #530035;">fill</span>=<span style="color: #530035;">None</span>, <span style="color: #530035;">stroke</span>=<span style="color: #530035;">None</span>, <span style="color: #530035;">strokewidth</span>=<span style="color: #530035;">None</span><span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="">[</span>clr1, clr2, clr3, ...<span style="">]</span>, w, h<span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span>layer<span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span>canvas<span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span>layer.<span style="">render</span><span style="">(</span><span style="">)</span><span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span>canvas.<span style="">flatten</span><span style="">(</span><span style="">)</span><span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">open</span><span style="">(</span>filename<span style="">)</span>.<span style="">read</span><span style="">(</span><span style="">)</span><span style="">)</span></pre></pre><pre class="python">canvas.<span style="">append</span><span style="">(</span>movieframe<span style="">)</span></pre></pre> <p> </p><p><span class="grey_box">Examples</span> </p><p>Consider we have the following images, <i>leaf.jpg</i> and <i>lily.tif</i>.</p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-leaf.jpg" /><br /><a href="/code/data/media/leaf.jpg" target="_self"> leaf.jpg</a></td> <td><a href="/code/data/media/lily.tif" target="_self"><img src="/code/data/media/coreimage-lily.jpg" /><br /> lily.tif</a></td> </tr> </tbody></table> <p>Core Image can use JPEG, GIF, PNG and TIFF images. If you are using images with an alpha channel the best way to import them is as transparent TIFF and not as a PNG (which can have jagged edges in Core Image).</p><p> </p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-layers1.jpg" /></td> <td> A canvas with two layers from image files is easy enough: <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
canvas.<span style="">draw</span><span style="">(</span><span style="">)</span></pre></pre>The <i>canvas.append()</i> method has four ptional parameters: the <i>x</i> and <i>y</i> position in pixels and <i>w</i> and <i>h</i> dimensions in pixels. The command returns the layer object. </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers2.jpg" /></td> <td> Opaque fill layers are created from a standard NodeBox <a href="/code/Reference_|_color()" target="_self">color()</a>. The layer will fill the entire canvas by default. <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">1.0</span>, <span style="">0.0</span>, <span style="">0.5</span><span style="">)</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers3.jpg" /></td> <td><a href="/code/Paths" target="_self">Paths</a> from NodeBox can be transformed to a pixel layers as well. The <i>canvas.append()</i> method has optional path parameters: <i>fill</i>, <i>background</i>, <i>stroke</i> (black, transparent and transparent colors by default) and <i>strokewidth</i>. <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">1.0</span>, <span style="">0.0</span>, <span style="">0.5</span><span style="">)</span><span style="">)</span></pre>font("Georgia-Italic", 40)<br />p = textpath("text", 0, 0)<br />l = canvas.append(p, fill=color(1))<br /></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers4.jpg" /></td> <td> Linear gradients can be defined as two colors: <br /><pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">1</span><span style="">)</span>, <span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers5.jpg" /></td> <td>Both linear and radial gradients are defined by two colors. If you also define the optional <i>type</i> parameter as "radial" you get a radial gradient. You control the range of the gradient center with the optional <i>spread</i> parameter (between 0.0 and 1.0). <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">1</span><span style="">)</span>, <span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span>, <span style="">type</span>=<span style="color: #ff0080;">"radial"</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers6.jpg" /></td> <td>You can also pass another canvas as a new layer. This way you have a subgroup of layers that stick together. <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span><span style="">)</span>
group = coreimage.<span style="">canvas</span><span style="">(</span><span style="">100</span>, <span style="">100</span><span style="">)</span>
group.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
group.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l = canvas.<span style="">appebd</span><span style="">(</span>group<span style="">)</span>
l.<span style="color: #530035;">rotate</span><span style="">(</span><span style="">45</span><span style="">)</span></pre></pre> </td> </tr> <tr><td><img src="/code/data/media/coreimage-layers7b.jpg" alt="coreimage-layers7b" /> <br /></td><td>If you have some byte data, for example image data downloaded from a site with the <a href="/code/Web" target="_self">Web</a> library: <pre class="python">web = <span style="color: #530035;">ximport</span><span style="">(</span><span style="color: #ff0080;">"web"</span><span style="">)</span>
url = <span style="color: #ff0080;">"http://nodebox.net/code/g/header.jpg"</span>
image_data = web.<span style="">download</span><span style="">(</span>url<span style="">)</span>
canvas = coreimage.<span style="">canvas</span><span style="">(</span><span style="">150</span>, <span style="">150</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span>image_data, x=<span style="">-190</span><span style="">)</span></pre></pre></td></tr><tr><td><img src="/code/data/media/coreimage-layers7c.jpg" alt="coreimage-layers7c" /></td><td>A layer from individual pixels can be created by supplying a list of colors and a width and a height (thanks to Duane Bailey):<pre class="python"><span style="color: #530035;">def</span> <span style='color:rgb(255,0,50)'>fractal</span><span style="">(</span>x, y, depth=<span style="">64</span><span style="">)</span>:
z = <span style="">complex</span><span style="">(</span>x, y<span style="">)</span>
o = <span style="">complex</span><span style="">(</span><span style="">0</span>, <span style="">0</span><span style="">)</span>
<span style="color: #530035;">for</span> i <span style="color: #530035;">in</span> <span style="">range</span><span style="">(</span>depth<span style="">)</span>:
<span style="color: #530035;">if</span> <span style="">abs</span><span style="">(</span>o<span style="">)</span> <= <span style="">2</span>: o = o*o + z
<span style="color: #530035;">else</span>:
<span style="color: #530035;">return</span> i
<span style="color: #530035;">return</span> <span style="">0</span> <span style="color: grey;">#default, black</span>
pixels = <span style="">[</span><span style="">]</span>
w = h = <span style="">150</span>
<span style="color: #530035;">for</span> i <span style="color: #530035;">in</span> <span style="">range</span><span style="">(</span>w<span style="">)</span>:
<span style="color: #530035;">for</span> j <span style="color: #530035;">in</span> <span style="">range</span><span style="">(</span>h<span style="">)</span>:
v = fractal<span style="">(</span><span style="">float</span><span style="">(</span>i<span style="">)</span>/w, <span style="">float</span><span style="">(</span>j<span style="">)</span>/h<span style="">)</span>
pixels.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span>v/<span style="">10.0</span>, v/<span style="">20.0</span>, v/<span style="">10.0</span><span style="">)</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span>pixels, w, h<span style="">)</span></pre></pre></td></tr></tbody></table> <p> </p><p>If you think <i>canvas.append()</i> is too generic, there are various aliases that make it more understandable what kind of layer you're creating (all return a new layer): <i>canvas.fill()</i>, <i>canvas.path()</i>, <i>canvas.gradient()</i>, <i>canvas.group()</i>, <i>canvas.bytes()</i>, <i>canvas.pixels()</i>. </p> <p> </p><p><span class="grey_box">Layer copies</span> </p><p>Existing layers in a canvas can be duplicated. The copy appears right above the duplicated layer:</p> <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
dupl = l.<span style="">duplicate</span><span style="">(</span><span style="">)</span></pre></pre> <p>You can copy layers from one canvas and append them to another canvas:</p> <pre class="python">offscreen = coreimage.<span style="">canvas</span><span style="">(</span><span style="">150</span>,<span style="">150</span><span style="">)</span>
l = offscreen.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>.<span style="">copy</span><span style="">(</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span>l<span style="">)</span></pre></pre> <p>You can pre-render layers with <i>layer.render()</i> (or a canvas with <i>canvas.flatten()</i>) once and then use them as new layers or in another canvas. The advantage is that all the transformations and filters are calculated only once instead of individually for each copy. You can think of this as "flattening" a layer. See also the chapter on <a href="Core_Image.html#dynamics" target="_self">dynamics and caching</a>. </p><p> </p><p><span class="grey_box">Layer type</span> </p><p>You can check what type of layer you are working with using the following properties:</p> <ul> <li><i>layer.is_file</i>: a layer created from an image file.</li> <li><i>layer.is_fill</i>: an opaque fill color.</li> <li><i>layer.is_gradient</i>: a linear or radial gradient.</li> <li><i>layer.is_linear_gradient</i>: a linear gradient.</li> <li><i>layer.is_radial_gradient</i>: a radial gradient.</li> <li><i>layer.is_path</i>: a layer created from a NodeBox path.</li><li><i>layer.is_pixels</i>: a layer created from a list of colors.<br /></li> <li><i>layer.has_layers</i>: a layer created from a canvas object.</li><li><i>layer.has_shadow</i>: a dropshadow will be rendered for this layer.<br /></li> <li><i>layer.is_mask</i>: a layer that is part of the alpha mask of another layer.</li> </ul> <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
<span style="color: #530035;">print</span> l.<span style="">is_file</span>
>>> <span style="color: #530035;">True</span></pre></pre> <p> </p> <hr /> <h2><a name="arranging_layers" title="arranging_layers"></a>Retrieving and arranging layers</h2> <p>A canvas object acts as a list of layers. With a for-loop you can address each layer it contains: </p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-layers7.jpg" /></td> <td> <pre class="python"><span style="color: #530035;">for</span> i <span style="color: #530035;">in</span> <span style="">range</span><span style="">(</span><span style="">20</span><span style="">)</span>:
canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
<span style="color: #530035;">for</span> layer <span style="color: #530035;">in</span> canvas:
layer.<span style="">x</span> = <span style="color: #530035;">random</span><span style="">(</span>canvas.<span style="">w</span><span style="">)</span>
layer.<span style="">y</span> = <span style="color: #530035;">random</span><span style="">(</span>canvas.<span style="">h</span><span style="">)</span></pre></pre> </td> </tr> </tbody></table> <p>Layers can be named and easily retrieved later on. The <i>canvas.append()</i> method has an optional <i>name</i> parameter. You can then search the canvas for layer names with the recursive <i>canvas.find()</i> command or address layers as canvas properties:</p> <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span>, name=<span style="color: #ff0080;">"bg"</span><span style="">)</span>
l = canvas.<span style="">find</span><span style="">(</span><span style="color: #ff0080;">"bg"</span><span style="">)</span>
<span style="color: #530035;">print</span> l.<span style="">name</span>, l.<span style="">x</span>, l.<span style="">y</span>
>>> bg, <span style="">75</span>, <span style="">75</span></pre></pre> <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span>, name=<span style="color: #ff0080;">"bg"</span><span style="">)</span>
l = canvas.<span style="">bg</span></pre></pre></p> <p> </p> <p><span class="grey_box">Layer order</span> </p><p>Each new layer is added to the top of the canvas. You can change the ordering of a layer with the following commands:</p> <ul> <li><i>layer.up()</i>: moves the layer up one position in the layer stack</li> <li><i>layer.down()</i>: moves the layer down one position in the layer stack</li> <li><i>layer.to_front()</i>: moves the layer to the foreground of the canvas</li> <li><i>layer.to_back()</i>: moves the layer to the background of the canvas</li> </ul><p> </p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-layers8.jpg" /></td> <td> <pre class="python">back = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
front = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
back.<span style="">to_front</span><span style="">(</span><span style="">)</span></pre></pre> </td> </tr> </tbody></table> <p>The <i>layer.index </i>property contains the layer's position in the canvas. Like any list in NodeBox the indices start from zero:</p> <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
<span style="color: #530035;">print</span> l.<span style="">index</span>
>>> <span style="">1</span></pre></pre> <p>The <i>layer.hide()</i> method excludes the layer from the output:</p> <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">hide</span><span style="">(</span><span style="">)</span></pre></pre> <p> </p> <hr /> <h2><a name="transforming_layers" title="transforming_layers"></a>Moving and transforming layers</h2> <p>Individual layers in the canvas can be moved, scaled, rotated, flipped, distorted and cropped. </p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-layers9.jpg" /></td> <td> You can use a layer's <i>x</i> and <i>y</i> properties to move it around. These properties store the layer's position measured in pixels from the top-left of the canvas. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">x</span> = <span style="">0</span>
l.<span style="">y</span> = <span style="">0</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers10.jpg" /></td> <td> The same can be achieved using the <i>layer.translate()</i> method. This command accepts two parameters, either absolute pixel values or relative positions between 0.0 and 1.0. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="color: #530035;">translate</span><span style="">(</span><span style="">1.0</span>, <span style="">1.0</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers11.jpg" /></td> <td> You can scale images using pixel size or relative size. By supplying two parameters you can scale width and height individually. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
<span style="color: #530035;">for</span> i <span style="color: #530035;">in</span> <span style="">range</span><span style="">(</span><span style="">10</span><span style="">)</span>:
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">x</span> = i*<span style="">20</span>
l.<span style="color: #530035;">scale</span><span style="">(</span><span style="">1.0</span> - i*<span style="">0.1</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers12.jpg" /></td> <td> Rotating layers is just as easy: <br /><pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
<span style="color: #530035;">for</span> i <span style="color: #530035;">in</span> <span style="">range</span><span style="">(</span><span style="">10</span><span style="">)</span>:
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="color: #530035;">rotate</span><span style="">(</span>i*<span style="">10</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers13.jpg" /></td> <td> There's also the <i>layer.flip_vertical()</i> and <i>layer.flip_horizontal() </i>methods of course. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>.<span style="">flip_vertical</span><span style="">(</span><span style="">)</span></pre></pre><p><i><i><br /> </i></i></p></td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers14.jpg" /></td> <td> The <i>layer.distort()</i> method has optional <i>dx0</i>, <i>dy0</i>, <i>dx1</i>, <i>dy1</i>, <i>dx2</i>, <i>dy2</i>, <i>dx3</i>, <i>dy3</i> parameters setting the displacement of the left top, right top, right bottom and left bottom corners of the layer (in pixels or between 0.0 and 1.0). <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">distort</span><span style="">(</span>dy0=<span style="">-500</span>, dx2=<span style="">-100</span><span style="">)</span></pre></pre><br /> </td> </tr> <tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers65.jpg" alt="coreimage-layers65" /></span> <br /></td><td>The <i>layer.crop()</i> cuts a box from the image, starting from the top left position, with the given width and height. Images are always cropped before they are rotated, scaled and distorted. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">crop</span><span style="">(</span><span style="">0</span>, <span style="">0</span>, <span style="">80</span>, <span style="">80</span><span style="">)</span></pre></pre></p> </td></tr></tbody></table> <p> </p> <p><span class="grey_box">Origin point</span> </p><p>By default, all layer transformations originate from the layer's center. However, you can change the layer's origin point, have the layer rotate from the bottom right corner for example. Let's turn on some of the visual aids in the Core Image library for a minute:</p> <pre class="python">canvas.<span style="">draw</span><span style="">(</span>helper=<span style="color: #530035;">True</span><span style="">)</span></pre></pre> <p> </p> <p><span class="media"><img src="/code/data/media/coreimage-layers16.jpg" height="520" width="751" /></span> </p> <p>We can clearly see the layer's bounding box and how it is positioned around the central origin point. The layer rotates from the center. When we call <i>layer.origin_bottom_left()</i> to change the layer's origin point to the bottom left, rotations will originate from over there. Also, now the layer's bottom left is at the center of the canvas instead of the layer's center. Think of the origin point as the layer's anchor/pivot/orbit.</p> <p><span class="media"><img src="/code/data/media/coreimage-layers17.jpg" height="520" width="751" /></span> </p> <p>The following commands set the origin point:</p> <ul> <li><i>layer.origin_top_left()</i></li> <li><i>layer.origin_top_right()</i></li> <li><i>layer.origin_top_center()</i></li> <li><i>layer.origin_bottom_left()</i></li> <li><i>layer.origin_bottom_right()</i></li> <li><i>layer.origin_bottom_center()</i></li> <li><i>layer.origin_left_center()</i></li> <li><i>layer.origin_right_center()</i></li> <li><i>layer.origin_center()</i></li> </ul> <p>Or you can just use <i>layer.origin()</i> to set it yourself:</p> <pre class="python"><span style="color: #530035;">print</span> l.<span style="">origin</span><span style="">(</span><span style="">0.23</span>, <span style="">1.07</span><span style="">)</span>
>>> <span style="">(</span><span style="">0.23</span>, <span style="">1.07</span><span style="">)</span></pre></pre> <p> </p><p><span class="grey_box">Layer bounds</span> </p><p>To get the bounding box coordinates of layer, use <i>layer.bounds()</i>:</p> <pre class="python"><span style="color: #530035;">print</span> l.<span style="">bounds</span><span style="">(</span><span style="">)</span>
>>> <span style="">(</span><span style="">200.0</span>, <span style="">78.647456721610681</span>, <span style="">409.52033810627165</span>, <span style="">288.167787843871</span><span style="">)</span></pre></pre> <p>To get the width and height of a transformed layer, use <i>layer.size()</i> or the <i>width</i> and <i>height</i> properties. Note that when you manipulate the layer with filters the actual rendered pixels may fall beyond the given bounds.</p> <pre class="python">w, h = l.<span style="color: #530035;">size</span><span style="">(</span><span style="">)</span>
<span style="color: #530035;">print</span> w, h
>>> <span style="">(</span><span style="">209.52033810627165</span>, <span style="">209.5203311222603</span><span style="">)</span></pre></pre><pre class="python"><span style="color: #530035;">print</span> l.<span style="">width</span>
<span style="color: #530035;">print</span> l.<span style="">height</span></pre></pre> <p>You can easily position a layer at the center of the canvas with the <i>layer.center()</i> method:</p><pre class="python">l.<span style="">center</span><span style="">(</span><span style="">)</span></pre></pre></p> <p> </p> <hr /> <h2><a name="layers_adjustments" title="layers_adjustments"></a>Adjusting layer brightness, contrast and saturation</h2> <p>Aside from placing and transforming multiple layers in a canvas, we can also modify the color information in each layer.</p> <p> </p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-layers18.jpg" /></td> <td> The layer's <i>brightness </i>property ranges between -1.0 and 1.0: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">brightness</span> = <span style="">0.25</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers19.jpg" /></td> <td> The layer's <i>contrast</i> property ranges between 0.25 and 4.0: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">contrast</span> = <span style="">1.5</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers20.jpg" /></td> <td> The layer's <i>saturation</i> property ranges between 0.0 and 2.0: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">saturation</span> = <span style="">2.0</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers21.jpg" /></td> <td> The <i>layer.desaturate()</i> method removes all color information: <br /><pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">desaturate</span><span style="">(</span><span style="">)</span>
<span style="color: #530035;">print</span> l.<span style="">saturation</span>
>>> <span style="">0.0</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers22.jpg" /></td> <td> The <i>layer.invert()</i> method inverts all colors in the layer: <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l.<span style="">invert</span><span style="">(</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">invert</span><span style="">(</span><span style="">)</span></pre></pre> </td> </tr> </tbody></table> <p> </p> <p>You can set a combination of brightness, contrast and saturation with the <i>layer.adjust()</i> method, which has three optional parameters <i>brightness</i>, <i>contrast</i> and <i>saturation</i>.</p> <p> </p> <hr /> <h2><a name="blend_modes" title="blend_modes"></a>Layer opacity and blending modes</h2> <p>Layers can be composited by adjusting their individual transparency or by applying blend modes to create all sorts of effects.</p> <p> </p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-layers23.jpg" /></td> <td> The <i>layer.blend()</i> command takes one parameter ranging between 0 and 100 or between 0.0 and 1.0: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">blend</span><span style="">(</span><span style="">25</span><span style="">)</span>
<span style="color: #530035;">print</span> l.<span style="">opacity</span>
>>> <span style="">0.25</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers24.jpg" /></td> <td> <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
<span style="color: #530035;">for</span> i <span style="color: #530035;">in</span> <span style="">range</span><span style="">(</span><span style="">10</span><span style="">)</span>:
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="color: #530035;">scale</span><span style="">(</span><span style="">0.5</span><span style="">)</span>
l.<span style="">x</span> = <span style="color: #530035;">random</span><span style="">(</span>canvas.<span style="">w</span><span style="">)</span>
l.<span style="">y</span> = <span style="color: #530035;">random</span><span style="">(</span>canvas.<span style="">h</span><span style="">)</span>
l.<span style="">blend</span><span style="">(</span><span style="color: #530035;">random</span><span style="">(</span><span style="">)</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers25.jpg" /></td> <td>Screen blend displays pixels that are lighter than those underneath. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">50</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">100</span><span style="">)</span>
l.<span style="">blend_screen</span><span style="">(</span><span style="">)</span></pre></pre><p>A similar effect is <i>layer.blend_lighten()</i>. </p> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers26.jpg" /></td> <td> Multiply blend displays pixels that are darker than those underneath. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">50</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">100</span><span style="">)</span>
l.<span style="">blend_multiply</span><span style="">(</span><span style="">)</span></pre></pre><p>A similar effect is <i>layer.blend_darken()</i>. </p></td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers27.jpg" /></td> <td> Overlay uses a combination of screen and multiply. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">50</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">100</span><span style="">)</span>
l.<span style="">blend_overlay</span><span style="">(</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers27b.jpg" /></td> <td> Soft light uses a combination of darken and lighten. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">50</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">100</span><span style="">)</span>
l.<span style="">blend_softlight</span><span style="">(</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers27c.jpg" /></td> <td> Hard light uses a combination of screen and multiply. <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">50</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span>, x=<span style="">100</span><span style="">)</span>
l.<span style="">blend_hardlight</span><span style="">(</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers28.jpg" /></td> <td> Applying the hue of the blend layer to layers underneath: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">1.0</span>,<span style="">0.0</span>,<span style="">0.5</span><span style="">)</span><span style="">)</span>
l.<span style="">blend_hue</span><span style="">(</span><span style="">50</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers29.jpg" /></td> <td> Applying the hue and saturation of the blend layer to layers underneath: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">1.0</span>,<span style="">0.0</span>,<span style="">0.5</span><span style="">)</span><span style="">)</span>
l.<span style="">blend_color</span><span style="">(</span><span style="">50</span><span style="">)</span></pre></pre> </td> </tr> </tbody></table> <p> </p> <p>Use the <i>layer.blendmode</i> property to check what blending mode the layer is using.</p> <pre class="python"><span style="color: #530035;">print</span> l.<span style="">blendmode</span>
>>> multiply</pre></pre> <p>You can set the opacity and blend mode together with the <i>layer.blend()</i> command:</p> <pre class="python">l.<span style="">blend</span><span style="">(</span><span style="">25</span>, mode=<span style="color: #ff0080;">"multiply"</span><span style="">)</span>
<span style="color: #530035;">print</span> l.<span style="">opacity</span>, l.<span style="">blendmode</span>
>>> <span style="">0.25</span>, <span style="color: #530035;">color</span></pre></pre><pre class="python">l.<span style="">blend</span><span style="">(</span><span style="color: #ff0080;">"multiply"</span><span style="">)</span></pre></pre> <p>The <i>layer.blend_normal()</i> command removes any blend mode from the layer.</p> <p> </p> <hr /> <h2><a name="alpha_masks" title="alpha_masks"></a>Applying alpha masks</h2> <p>The layer's alpha mask stores information where the layer shines through and where it is opaque. Since the <i>layer.mask</i> property is a canvas object, it's just as easy to work with alpha layers than it is with normal layers. You can position, transform, adjust, blend and filter them just as any other layer.</p> <p> </p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-layers30.jpg" /></td> <td> Applying a linear gradient alpha mask to the lily: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
m = l.<span style="">mask</span>.<span style="">gradient</span><span style="">(</span><span style="">)</span>
m.<span style="color: #530035;">rotate</span><span style="">(</span><span style="">45</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers31.jpg" /></td> <td> Using a NodeBox path as a mask: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
<span style="color: #530035;">font</span><span style="">(</span><span style="color: #ff0080;">"Georgia-Italic"</span>, <span style="">50</span><span style="">)</span>
p = <span style="color: #530035;">textpath</span><span style="">(</span><span style="color: #ff0080;">"text"</span>, <span style="">0</span>, <span style="">0</span><span style="">)</span>
m = l.<span style="">mask</span>.<span style="">append</span><span style="">(</span>p<span style="">)</span>
m.<span style="">y</span> += <span style="">25</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers32.jpg" /></td> <td> Using the lily as a mask for a gradient layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0.4</span>,<span style="">0.0</span>,<span style="">0.2</span><span style="">)</span><span style="">)</span>
pink = <span style="color: #530035;">color</span><span style="">(</span><span style="">1.0</span>,<span style="">0.0</span>,<span style="">0.5</span><span style="">)</span>
white = <span style="color: #530035;">color</span><span style="">(</span><span style="">1.0</span>,<span style="">1.0</span>,<span style="">1.0</span><span style="">)</span>
l = canvas.<span style="">gradient</span><span style="">(</span>pink, white<span style="">)</span>
l.<span style="">mask</span>.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers33.jpg" /></td> <td> Complex mask made up of multiple layers: <pre class="python">l = c.<span style="">gradient</span><span style="">(</span>pink, white<span style="">)</span>
<span style="color: #530035;">for</span> i <span style="color: #530035;">in</span> <span style="">range</span><span style="">(</span><span style="">3</span><span style="">)</span>:
m = l.<span style="">mask</span>.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
m.<span style="color: #530035;">scale</span><span style="">(</span><span style="">1</span>-i*<span style="">0.4</span><span style="">)</span>
m.<span style="color: #530035;">rotate</span><span style="">(</span><span style="">20</span>*i<span style="">)</span>
m.<span style="">blend</span><span style="">(</span><span style="color: #ff0080;">"softlight"</span><span style="">)</span>
m.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"zoomblur"</span>, amount=i*<span style="">25</span><span style="">)</span></pre></pre> </td> </tr> </tbody></table> <p> </p> <hr /> <h2><a name="filters" title="filters"></a>Layer filters</h2> <p>The Core Image library supports a number of filters that manipulate the pixels in a layer. Blur and sharpen are standard so you can set these as properties:</p> <p> </p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-layers34.jpg" /></td> <td> The <i>layer.blur</i> takes one parameter ranging between 0.0 and 100.0: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">blur</span> = <span style="">2</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers35.jpg" /></td> <td> Sharpening the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">sharpen</span> = <span style="">10</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-layers36.jpg" /></td> <td>Other filters use the <i>layer.filter()</i> method: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"zoomblur"</span>, dx=<span style="">25</span><span style="">)</span></pre></pre> </td> </tr> </tbody></table> <p> </p> <hr /> <p><span class="grey_box">Filter reference </span> </p><p>There are many other filters like the zoom blur above. Each <i>layer.filter()</i> command takes its own optional parameters to tweak. Scroll down for visual examples.<br /></p><p><b>Zoom blur</b> <br />Simulates the effect of zooming the camera while capturing the layer. Parameters are <i>dx</i>, <i>dy</i> and <i>amount</i> ranging between 0.0 and 200.0.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"zoomblur"</span>, amount=<span style="">20</span>, dx=<span style="">0</span>, dy=<span style="">0</span><span style="">)</span></pre></pre><p><b>Motion blur</b><br />Simulates a directional blur. Parameters are <i>radius</i> between 0.0 and 100.0 and <i>angle</i>.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"motionblur"</span>, radius=<span style="">20</span>, angle=<span style="">0</span><span style="">)</span></pre></pre><p><b>Noise reduction</b><br /> Edges in the layer below a threshold are blurred, edges above are sharpened. Parameters are noise between 0.0 and0.1 and sharpness between 0.0 and 2.0.<br /> </p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"noisereduction"</span>, noise=<span style="">0.02</span>, sharpness=<span style="">0.4</span></pre></pre><p><b>Bump distortion</b> <br />Creates a bump or pinch from a point in the layer. Parameters are <i>dx</i>, <i>dy</i>, <i>radius</i> between 0.0 and 600.0 and <i>scale</i> between -1.0 and 1.0.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"bumpdistortion"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, radius=<span style="">300</span>, <span style="color: #530035;">scale</span>=<span style="">0.5</span><span style="">)</span></pre></pre><p><b>Bump distortion</b> <b>linear | stretch</b> (Mac OS X 10.5 and up)<br />Creates a bump or pinch from a line in the layer. Parameters are <i>dx</i>, <i>dy</i>, <i>radius</i> between 0.0 and 600.0, <i>scale</i> between -1.0 and 1.0 and <i>angle</i>.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"stretch"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, radius=<span style="">300</span>, <span style="color: #530035;">scale</span>=<span style="">0.5</span>, angle=<span style="">0</span><span style="">)</span></pre></pre><p><b>Hole distortion</b> <br />Pushes the layer's pixels outwards. Parameters are <i>dx</i>, <i>dy</i>, and a <i>radius</i> between 0.0 and 1000.0.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"holedistortion"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, radius=<span style="">300</span><span style="">)</span></pre></pre><p><b>Circle splash distortion</b> <br />Pushes the layer's pixels outwards on a circle. Parameters are <i>dx</i>, <i>dy</i>, <i>radius</i> between 0.0 and 1000.0 . <br /></p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"circlesplash"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, radius=<span style="">150</span><span style="">)</span></pre></pre><p><b>Twirl distortion<br /></b>Generates a wave motion in the layer. Parameters are <i>dx</i>, <i>dy</i>, <i>radius</i> between 0.0 and 500.0 and <i>angle</i>.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"twirl"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, radius=<span style="">150</span>, angle=<span style="">100</span><span style="">)</span></pre></pre><p><b>Circular wrap</b> <br />Wraps the layer around a transparent circle. Parameters are <i>radius</i> between 0.0 and 500.0 and <i>angle</i>.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"circularwrap"</span>, radius=<span style="">150</span>, angle=<span style="">100</span><span style="">)</span></pre></pre><p><b>Kaleidoscope</b><br />Generates fractal-like output. Parameters are <i>dx</i>, <i>dy</i> and <i>count</i> between 0 and 100.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"kaleidoscope"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, count=<span style="">10</span><span style="">)</span></pre></pre><p><b>Triangle tile</b><br /> Generates fractal-like output. Parameters are <i>dx</i>, <i>dy</i> and <i>angle</i> and <i>width</i>.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"triangletile"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, angle=<span style="">10</span>, width=<span style="">100</span><span style="">)</span></pre></pre><p><b>Parallelogram tile</b> (Mac OS X 10.5 and up)<br /> Generates fractal-like output. Parameters are <i>dx</i>, <i>dy</i> and <i>angle</i>, <i>width</i> and <i>tilt</i> angle.<br /></p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"parallelogramtile"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, angle=<span style="">10</span>, width=<span style="">100</span>, tilt=<span style="">90</span><span style="">)</span></pre></pre><p><b>Perspective tile</b><br />Distorts the base layer and copies that on a plane. Parameters are <i>dx0</i>, <i>dy0</i>, <i>dx1</i>, <i>dy1</i>, <i>dx2</i>, <i>dy2</i>, <i>dx3</i>, <i>dy3</i> representing the corners of the layer to distort.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"perspectivetile"</span>, dx0=<span style="">0</span>, dy0=<span style="">0</span>, dx1=<span style="">0</span>, dy1=<span style="">0</span>,
dx2=<span style="">0</span>, dy2=<span style="">0</span>, dx3=<span style="">0</span>, dy3=<span style="">0</span><span style="">)</span></pre></pre><p><b>Starshine generator</b><br />A generator that creates stars and sunbursts on the layer (which is usually a transparent color). Parameters are <i>dx</i>, <i>dy</i>, <i>radius</i> between 0.0 and 300.0, <i>x_scale</i> between 0.0 and 100.0, <i>x_angle</i>, <i>x_width</i> and <i>epsilon</i> between -8.0 and 8.0.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"starshine"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, radius=<span style="">25</span>,
x_scale=<span style="">10</span>, x_angle=<span style="">0</span>, x_width=<span style="">0.5</span>, epsilon=<span style="">-5.0</span><span style="">)</span></pre></pre><p><b>Checkerboard generator</b><br />A generator that creates a checkerboard pattern on the layer (which is usually a transparent color). Parameters are clr1 and clr2 (black and white by default), width between 0.0 and 800.0, and sharpness between 0.0 and 1.0.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"checkerboard"</span>, clr1=<span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span>, clr2=<span style="color: #530035;">color</span><span style="">(</span><span style="">1</span><span style="">)</span>,
width=<span style="">80</span>, sharpness=<span style="">1.0</span><span style="">)</span></pre></pre><p><b>Bloom</b><br />Adds a hazy glow to the layer by softening the edges. Parameters are <i>radius</i> between 0.0 and 100.0 and <i>intensity</i> between 0.0 and 1.0.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"bloom"</span>, radius=<span style="">10</span>, intensity=<span style="">1.0</span><span style="">)</span></pre></pre><p><b>Pixelate</b><br />Divides the image into rectangular cells. It takes one optional parameter <i>scale</i> between 1.0 and 100.0</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"pixelate"</span>, <span style="color: #530035;">scale</span>=<span style="">8</span><span style="">)</span></pre></pre><p><b>Crystallize</b><br /> Divides the image into polygonal cells. It takes one optional parameter <i>radius</i> between 1.0 and 100.0</p> <pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"crystallize"</span>, radius=<span style="">20</span><span style="">)</span></pre></pre><p><b>Dotscreen</b><br />Simulates the dot patterns of a halftone screen. Parameters are <i>dx</i>, <i>dy</i>, <i>angle</i> between 0 and 360, <i>width</i> between 1 and 50, and <i>sharpness</i> between 0.0 and 1.0.</p> <pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"dotscreen"</span>, dx=<span style="">0</span>, dy=<span style="">0</span>, angle=<span style="">0</span>, width=<span style="">6</span>, sharpness=<span style="">0.7</span><span style="">)</span></pre></pre><p><b>Lighting</b><br />Adds a light source to the layer. Parameters are <i>dx0</i>, <i>dy0</i>, <i>dz0</i> between 0 and 1000 represting the height of the light source, <i>dx1</i> and <i>dy1</i> representing where the light is shining, <i>brightness</i> between 0.0 and 10.0, <i>concentration</i> between 0.0 and 1.0 representing the cone of the light beam and <i>color</i>.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"lighting"</span>, dx0=<span style="">100</span>, dy0=<span style="">100</span>, dz0=<span style="">300</span>, dx1=<span style="">0</span>, dy1=<span style="">0</span>,
brightness=<span style="">3.0</span>, concentration=<span style="">0.3</span>,
<span style="color: #530035;">color</span>=<span style="color: #530035;">None</span>, helper=<span style="color: #530035;">False</span><span style="">)</span></pre></pre><p><b>Shading</b><br />Adds texturing to the layer. You can pass it a canvas object to apply as a texture. Parameters are <i>dx</i>, <i>dy</i>, <i>radius</i> between 0.0 and 300.0 and <i>texture</i> which is a canvas object.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"shading"</span>, radius=<span style="">20</span>, texture=<span style="color: #530035;">None</span>, dx=<span style="">0</span>, dy=<span style="">0</span><span style="">)</span></pre></pre><p><b>Line overlay </b>(Mac OS X 10.5 and up)<br />Simulates a sketch of the layer by outlining the edges in black, after performing noise reduction. Parameters are <i>noise</i> between 0.0 and 0.01, <i>sharpness</i> between 0.0 and 2.0, <i>intensity</i> between 0 and 200 and <i>contrast</i> between 25 and 200.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"lineoverlay"</span>, noise=<span style="">0.07</span>, sharpness=<span style="">0.71</span>
intensity=<span style="">1.0</span>, threshold=<span style="">0.1</span>, contrast=<span style="">50</span><span style="">)</span></pre></pre><p><b>Page curl</b><br />Curls a corner of the layer. You can pass the <i>back</i> parameter a canvas object to use as backside. By default the backside is a mirrored version of the layer. It can also be a color or "pattern", in which case the backside is a triangle-tiled pattern. Parameters are <i>time</i> between 0.0 and 1.0, <i>radius</i> between 0 and 200 and <i>angle</i> between 0 and 360. </p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"pagecurl"</span>, <span style="">time</span>=<span style="">0.4</span>, radius=<span style="">75</span>, angle=<span style="">45</span>, back=<span style="color: #530035;">None</span><span style="">)</span></pre></pre><p><b>Levels</b><br />Provides control over each RGBA color channel in the layer. Parameters are <i>r</i>, <i>g</i>, <i>b</i> and <i>a</i> which can be numbers between 0.0 and 1.0 or four-tuples if you want to do complex things like increase the blue inside the R channel.</p><ul> </ul><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"levels"</span>, r=<span style="">1.0</span>, g=<span style="">1.0</span>, b=.<span style="">0</span>, a=.<span style="">0</span><span style="">)</span></pre></pre> <p><b>Edges</b><br />Finds all the edges in an image and displays them in a color.</p><pre class="python">layer.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"edges"</span>, intensity=<span style="">1.0</span><span style="">)</span></pre></pre></p> <table border="0"> <tbody><tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers37.jpg" /></span></td> <td> Applying the zoom blur to the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"zoomblur"</span>, dy=<span style="">25</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers38.jpg" /></span></td> <td> Applying the motion blur to the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"motionblur"</span>, angle=<span style="">45</span>, radius=<span style="">50</span><span style="">)</span></pre></pre> </td> </tr> <tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers38b.jpg" alt="coreimage-layers38b" /></span></td><td> Applying noise reduction to the layer:<pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"noisereduction"</span>, noise=<span style="">0.01</span>, sharpness=<span style="">1.0</span><span style="">)</span></pre></pre></td></tr><tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers39.jpg" /></span></td> <td> Applying bump distortion to the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"bumpdistortion"</span>, <span style="color: #530035;">scale</span>=<span style="">0.75</span>, dy=<span style="">-35</span><span style="">)</span></pre></pre> </td> </tr> <tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers38c.jpg" alt="coreimage-layers38c" /></span></td><td> Applying linear bump distortion to the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"stretch"</span>, radius=<span style="">60</span>, <span style="color: #530035;">scale</span>=<span style="">0.0</span>, dy=<span style="">60</span><span style="">)</span></pre></pre></td></tr><tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers39b.jpg" /></span></td> <td> Applying hole distortion to the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"holedistortion"</span>, radius=<span style="">40</span><span style="">)</span></pre></pre> </td> </tr> <tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers59.jpg" alt="coreimage-layers59" /></span> <br /></td><td> Applying circle splash distortion to the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"circlesplash"</span>, radius=<span style="">45</span><span style="">)</span></pre></pre> </td></tr><tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers40.jpg" /></span></td> <td> Applying the famous twirl filter to the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"twirl"</span>, radius=<span style="">150</span><span style="">)</span></pre></pre> </td> </tr> <tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers57.jpg" alt="coreimage-layers57" /></span> <br /></td><td>Applying the circular wrap filter to the layer:<pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"twirl"</span>, radius=<span style="">150</span><span style="">)</span></pre></pre></p> </td></tr><tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers41.jpg" /></span></td> <td> Applying a kaleidoscope to the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"kaleidoscope"</span>, count=<span style="">5</span><span style="">)</span></pre></pre> </td> </tr> <tr><td> <span class="image_border"><img src="/code/data/media/coreimage-layers42b.jpg" alt="coreimage-layers42b" /></span></td><td>Applying a triangle tile to the layer:<pre class="python">l = c.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"triangletile"</span>, dx=<span style="">-30</span>, dy=<span style="">-30</span>, width=<span style="">40</span><span style="">)</span></pre></pre></td></tr><tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers42c.jpg" alt="coreimage-layers42c" /></span> <br /></td><td> Applying a parallelogram tile to the layer:<pre class="python">l = c.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"triangletile"</span>, dx=<span style="">3</span>, width=<span style="">40</span>, tilt=<span style="">-45</span><span style="">)</span></pre></pre></td></tr><tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers42.jpg" /></span></td> <td> Applying a perspective tile to the layer: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="color: #530035;">scale</span><span style="">(</span><span style="">0.6</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"perspectivetile"</span>, dx0=<span style="">50</span>, dy1=<span style="">30</span>, dy2=<span style="">-50</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers43.jpg" /></span></td> <td> Generating starshine: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0</span>, <span style="">0</span><span style="">)</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"starshine"</span>, x_width=<span style="">0.3</span><span style="">)</span></pre></pre> </td> </tr> <tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers58.jpg" alt="coreimage-layers58" /></span> <br /></td><td> Generating a checkerboard pattern: <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0</span>, <span style="">0</span><span style="">)</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"checkerboard"</span>, clr1=<span style="color: #530035;">color</span><span style="">(</span><span style="">0.35</span><span style="">)</span>, width=<span style="">8</span><span style="">)</span></pre></pre> </td></tr><tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers44.jpg" /></span></td> <td> Applying a bloom filter: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"bloom"</span><span style="">)</span></pre></pre> </td> </tr> <tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers55.jpg" alt="coreimage-layers55" /></span> <br /></td><td>Applying rectangular pixelation:<pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"pixelate"</span>, <span style="color: #530035;">scale</span>=<span style="">7</span><span style="">)</span></pre></pre></td></tr><tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers56.jpg" alt="coreimage-layers56" /></span></td><td>Applying polygonal pixelation: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"crystallize"</span>, <span style="color: #530035;">scale</span>=<span style="">15</span><span style="">)</span></pre></pre> </td></tr><tr><td><img src="/code/data/media/coreimage-layers63.jpg" alt="coreimage-layers63" /> <br /></td><td>Applying halftone effect:<pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"dotscreen"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"coreimage-flower.png"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"dotscreen"</span><span style="">)</span></pre></pre></td></tr><tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers45.jpg" /></span></td> <td> Applying lighting: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"lighting"</span>, dx1=<span style="">-55</span>, dy0=<span style="">55</span>, dz0=<span style="">45</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers46.jpg" /></span></td> <td> Applying shading: <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span><span style="">)</span>
p = supershape.<span style="">path</span><span style="">(</span><span style="">50</span>, <span style="">60</span>, <span style="">60</span>, <span style="">60</span>, <span style="">12</span>, <span style="">2</span>, <span style="">0.7</span>, <span style="">-2</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span>p, <span style="color: #530035;">fill</span>=<span style="color: #530035;">color</span><span style="">(</span><span style="">1</span><span style="">)</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"shading"</span>, dx=<span style="">31</span>, radius=<span style="">5.0</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers47.jpg" /></span></td> <td> <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span><span style="">)</span>
p = supershape.<span style="">path</span><span style="">(</span><span style="">50</span>, <span style="">60</span>, <span style="">60</span>, <span style="">60</span>, <span style="">12</span>, <span style="">2</span>, <span style="">0.7</span>, <span style="">-2</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span>p, <span style="color: #530035;">fill</span>=<span style="color: #530035;">color</span><span style="">(</span><span style="">1</span><span style="">)</span><span style="">)</span>
t = coreimage.<span style="">canvas</span><span style="">(</span><span style="">150</span>, <span style="">150</span><span style="">)</span>
t.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"shading"</span>, dx=<span style="">31</span>, radius=<span style="">20.0</span>, texture=t<span style="">)</span></pre></pre> </td> </tr> <tr><td><span class="image_border"></span><span class="image_border"><img src="/code/data/media/coreimage-layers64.jpg" alt="coreimage-layers64" /></span></td><td>Applying line overay:<pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"lineoverlay"</span>, noise=<span style="">0.08</span>, sharpness=<span style="">0.1</span>,
threshold=<span style="">0.3</span>, contrast=<span style="">2</span>, intensity=<span style="">1</span><span style="">)</span></pre></pre></td></tr><tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers54.jpg" alt="coreimage-layers54" /></span></td><td> Applying a page curl transition:<pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"pagecurl"</span>, <span style="">time</span>=<span style="">0.55</span>, angle=<span style="">45</span>, radius=<span style="">60</span><span style="">)</span></pre></pre></td></tr><tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers48.jpg" /></span></td> <td> Applying color level adjustments: <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"levels"</span>, g=<span style="">0.6</span>, b=<span style="">1.6</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><span class="image_border"><img src="/code/data/media/coreimage-layers60.jpg" alt="coreimage-layers60" /></span></td> <td> Using levels for a custom dropshadow (with zoomblur for exanple): <pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"levels"</span>, r=<span style="">0</span>, g=<span style="">0</span>, b=<span style="">0</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"zoomblur"</span>, dx=<span style="">-20</span>, dy=<span style="">40</span><span style="">)</span>
l.<span style="">blend</span><span style="">(</span><span style="">75</span><span style="">)</span>
l.<span style="">x</span> += <span style="">10</span>; l.<span style="">y</span> += <span style="">10</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span></pre></pre> </td> </tr> <tr><td><span class="image_border"><img src="/code/data/media/coreimage-layers62.jpg" alt="coreimage-layers62" /></span> <br /></td><td>Finding edges:<pre class="python">canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">0</span><span style="">)</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"edges"</span>, intensity=<span style="">2.0</span><span style="">)</span></pre></pre></td></tr></tbody></table> <p> </p> <p><span class="grey_box">Filter aliases</span> </p><p>All the information about filters and their parameters is stored in the canvas renderer. Take a look at:</p> <pre class="python"><span style="color: #530035;">print</span> canvas.<span style="">renderer</span>.<span style="">aliases</span>.<span style="">keys</span><span style="">(</span><span style="">)</span>
>>> <span style="">[</span><span style="color: #ff0080;">'starshine'</span>, <span style="color: #ff0080;">'shading'</span>, <span style="color: #ff0080;">'bumpdistortion'</span>, <span style="color: #ff0080;">'zoomblur'</span>, <span style="color: #ff0080;">'motionblur'</span>,
>>> <span style="color: #ff0080;">'levels'</span>, <span style="color: #ff0080;">'twirl'</span>, <span style="color: #ff0080;">'perspectivetile'</span>, <span style="color: #ff0080;">'lighting'</span>,
>>> <span style="color: #ff0080;">'bloom'</span>, <span style="color: #ff0080;">'kaleidoscope'</span><span style="">]</span>
<span style="color: #530035;">print</span> canvas.<span style="">renderer</span>.<span style="">aliases</span><span style="">[</span><span style="color: #ff0080;">"levels"</span><span style="">]</span>
>>> CIColorMatrix
<span style="color: #530035;">print</span> canvas.<span style="">renderer</span>.<span style="">filters</span><span style="">[</span><span style="color: #ff0080;">"CIColorMatrix"</span><span style="">]</span>
>>> <span style="">{</span><span style="color: #ff0080;">'a'</span>: <span style="">1.0</span>, <span style="color: #ff0080;">'interface'</span>: <span style="color: #530035;">False</span>, <span style="color: #ff0080;">'r'</span>: <span style="">1.0</span>, <span style="color: #ff0080;">'b'</span>: <span style="">1.0</span>, <span style="color: #ff0080;">'g'</span>: <span style="">1.0</span><span style="">}</span></pre></pre> <p> </p><hr size="2" width="100%" /><h2><a title="dropshadows" name="dropshadows"></a>Layer dropshadows</h2><p>You can add a shadow to each layer in the canvas, in the same way as you can add a shadow to NodeBox primitives with the <a href="/code/Colors" target="_self">Colors</a> library: </p><pre class="python">layer.<span style="">shadow</span><span style="">(</span>dx=<span style="">10</span>, dy=<span style="">10</span>, alpha=<span style="">0.75</span>, blur=<span style="">8</span><span style="">)</span></pre></pre></p> <table><tbody><tr><td><img src="/code/data/media/coreimage-layers61.jpg" alt="coreimage-layers61" /></td><td>Default dropshadow: <br /><pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
l.<span style="">shadow</span><span style="">(</span><span style="">)</span></pre></pre></td></tr></tbody></table><p> </p> <hr /> <h2><a name="pixels" title="pixels"></a>Working with layer pixels</h2> <p>To create a canvas layer from a list of pixel colors, use <i>canvas.append()</i> as explained in the section on <a href="Core_Image.html#adding_layers" target="_self">adding layers</a>. </p><p>You can access individual pixels in a layer or retrieve information about the minimum, maximum and average pixel values. The <i>layer.pixels()</i> gives you a pixels object that is a list of colors with some extra methods: <i>pixels.min()</i>, <i>pixels.max()</i>, <i>pixels.average()</i>, and <i>pixels.</i><i>get_pixel()</i>, <i>pixels.</i><i>set_pixel()</i> and <i>pixels.</i><i>get_range().</i><i> </i>These return a <a href="/code/Reference_|_color()" target="_self">color</a>. </p> <pre class="python">l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
p = l.<span style="">pixels</span><span style="">(</span><span style="">)</span></pre></pre><pre class="python"><span style="color: #530035;">print</span> p.<span style="">is_rgb</span><span style="">(</span><span style="">)</span>
>>> <span style="color: #530035;">True</span></pre></pre><pre class="python"><span style="color: #530035;">print</span> p.<span style="">has_alpha</span><span style="">(</span><span style="">)</span>
>>> <span style="color: #530035;">False</span></pre></pre><pre class="python"><span style="color: #530035;">print</span> <span style="color: #ff0080;">"min:"</span>, p.<span style="">min</span><span style="">(</span><span style="">)</span>
<span style="color: #530035;">print</span> <span style="color: #ff0080;">"max:"</span>, p.<span style="">max</span><span style="">(</span><span style="">)</span>
<span style="color: #530035;">print</span> <span style="color: #ff0080;">"avg:"</span>, p.<span style="">average</span><span style="">(</span><span style="">)</span>
>>> <span style="">min</span>: <span style="color: #530035;">color</span><span style="">(</span><span style="">0.02</span>, <span style="">0.03</span>, <span style="">0.00</span><span style="">)</span>
>>> <span style="">max</span>: <span style="color: #530035;">color</span><span style="">(</span><span style="">0.44</span>, <span style="">0.54</span>, <span style="">0.49</span><span style="">)</span>
>>> avg: <span style="color: #530035;">color</span><span style="">(</span><span style="">0.18</span>, <span style="">0.31</span>, <span style="">0.19</span><span style="">)</span></pre></pre><pre class="python"><span style="color: #530035;">print</span> p.<span style="">get_pixel</span><span style="">(</span><span style="">100</span>, <span style="">100</span><span style="">)</span>
>>> <span style="color: #530035;">color</span><span style="">(</span><span style="">0.09</span>, <span style="">0.11</span>, <span style="">0.03</span><span style="">)</span></pre></pre><pre class="python"><span style="color: #530035;">print</span> p.<span style="">w</span>, p.<span style="">h</span>
>>> <span style="">150</span>, <span style="">150</span></pre></pre> <p>There's also a <i>pixels.</i><i>set_pixel()</i>. It takes an <i>x</i> and <i>y</i> position and a <i>color</i> as parameters. When you modify pixels in this way, changes will not automatically be committed to the layer. You need to <b>explicitly call</b> <i>pixels.</i><i>update()</i> on the pixels object when you're done modifying. Also, remember that pixel operations can be time and memory intensive. <br /></p><pre class="python">p = l.<span style="">pixels</span><span style="">(</span><span style="">)</span>
p.<span style="">set_pixel</span><span style="">(</span><span style="">100</span>, <span style="">100</span>, <span style="color: #530035;">color</span><span style="">(</span><span style="">0</span>,<span style="">1</span>,<span style="">0</span><span style="">)</span><span style="">)</span>
p.<span style="">update</span><span style="">(</span><span style="">)</span></pre></pre></p> <p>The <i>pixels.get_range()</i> method returns a list of colors. It takes <i>x</i> and <i>y</i> and <i>w</i> and <i>h</i> parameters. This way you can select a rectangular box of pixels from the layer. </p><p>As a fun experiment we can transform the pixels to NodeBox vector rectangles. We measure the RGB values in every tenth pixels and apply those colors to a grid of 10 x 10 rectangles:</p> <p> </p> <p><span class="media"><img src="/code/data/media/coreimage-layers50.jpg" height="520" width="751" /></span> </p> <p> </p> <p><span class="grey_box">Pixel histogram</span> </p><p>The <i>pixels.histogram()</i> extracts a histogram from the layer's pixel data. The return value is a list with either three (R, G and B) or four (R, G, B, A) elements. Each element is a list of 254 elements ranging between 0.0 and 1.0. For example: if <i>pixels.histogram()[0][100]</i> would be 0.0, this means that the layer has no pixels where the red is 100. If <i>pixels.histogram()[1][10]</i> would be 1.0, this means that the layer's pixels usually have a green value of 10.</p> <p>Let's have a look at the pixel values of the leaf image using another one of the visual aids in the Core Image library:</p> <p> </p> <p><span class="media"><img src="/code/data/media/coreimage-layers51.jpg" height="520" width="751" /></span> </p> <p> </p> <hr /> <h2><a name="export_the_canvas" title="export_the_canvas"></a>Exporting the canvas to JPEG, GIF, PNG or TIFF</h2> <p>It's easy to export the canvas as an compressed image for the web or a TIFF with CMYK colors. If your image has few different colors (e.g. opaque color planes with text) you can use export a lossless GIF for the web. If your image contains photos, use a JPEG with compression. When you are going to paper print your image, use a CMYK TIFF.</p> <p> </p> <table border="0"> <tbody><tr> <td><img src="/code/data/media/coreimage-flower.jpg" /></td> <td> A JPEG for the web with 40% compression: <pre class="python">canvas = coreimage.<span style="">canvas</span><span style="">(</span><span style="">150</span>, <span style="">150</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
canvas.<span style="">export</span><span style="">(</span><span style="color: #ff0080;">"flower.jpg"</span>, compression=<span style="">0.6</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-flower-tif.jpg" /></td> <td> A TIFF in CMYK with LZW-compression: <pre class="python">canvas = coreimage.<span style="">canvas</span><span style="">(</span><span style="">150</span>, <span style="">150</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
canvas.<span style="">export</span><span style="">(</span><span style="color: #ff0080;">"flower.tif"</span>,
cmyk=<span style="color: #530035;">True</span>, compression=<span style="color: #530035;">True</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-flower.png" /></td> <td> A PNG image with a transparent background: <pre class="python">canvas = coreimage.<span style="">canvas</span><span style="">(</span><span style="">150</span>, <span style="">150</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
canvas.<span style="">export</span><span style="">(</span><span style="color: #ff0080;">"flower.png"</span><span style="">)</span></pre></pre> </td> </tr> <tr> <td><img src="/code/data/media/coreimage-flower.gif" /></td> <td> A GIF image file: <pre class="python">canvas = coreimage.<span style="">canvas</span><span style="">(</span><span style="">150</span>, <span style="">150</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #530035;">color</span><span style="">(</span><span style="">1.0</span>, <span style="">0.0</span>, <span style="">0.5</span><span style="">)</span><span style="">)</span>
<span style="color: #530035;">font</span><span style="">(</span><span style="color: #ff0080;">"Georgia-Italic"</span>, <span style="">40</span><span style="">)</span>
p = <span style="color: #530035;">textpath</span><span style="">(</span><span style="color: #ff0080;">"text"</span>, <span style="">0</span>, <span style="">0</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span>p, <span style="color: #530035;">fill</span>=<span style="color: #530035;">color</span><span style="">(</span><span style="">1</span><span style="">)</span><span style="">)</span>
canvas.<span style="">export</span><span style="">(</span><span style="color: #ff0080;">"flower.gif"</span><span style="">)</span></pre></pre> </td> </tr> </tbody></table> <p> </p> <p>Some important things to know:</p> <ul> <li><p>A generic CMYK profile is used. This means that the canvas renderer makes no attempt to correctly remap colors that are outside the CMYK scope: pure RGB red and other high intensity colors may contain pixel errors. This is especially true for layers created from paths. It is your responsibility to create paths in CMYK-safe colors. Usually everything is OK so long as you use paths created with NodeBox <a href="/code/Reference_|_color()">color()</a> colors.</p></li><li>When you export Core Image compositions from the NodeBox file menu, PDF export won't work under Mac OS X 10.5. You can export JPEG, GIF and PNG however.<br /></li> </ul> <p> </p> <hr /> <h2><a name="drawing_the_canvas" title="drawing_the_canvas"></a>Drawing the canvas in NodeBox</h2> <p>Merging all the layers in a canvas and drawing the result in NodeBox is easy:</p> <pre class="python">canvas = coreimage.<span style="">canvas</span><span style="">(</span><span style="">150</span>, <span style="">150</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
l = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"lily.tif"</span><span style="">)</span>
canvas.<span style="">draw</span><span style="">(</span><span style="">0</span>, <span style="">0</span><span style="">)</span></pre></pre> <p>The <i>canvas.draw()</i> command takes two optional parameters: the x and y position.</p> <p>Note that when you export a PDF that contains a canvas with a transparent background it might have pixel errors.<br /> <br /></p> <hr /> <h2><a name="helpers" title="helpers"></a>Working with helpers and interfaces</h2> <p>Some things in the Core Image library are a little hard to do or grasp without visual feedback. That's why the library has a few helpers and interfaces. There's a helper for the <i>canvas.draw()</i> command that displays rulers and a bounding box for each of the layers. It's already shown in the documentation on <a href="Core_Image.html#transforming_layers">transforming layers</a>. There's also a helper for the pixels histogram shown in the documentation on <a href="Core_Image.html#pixels">working with pixels</a>.</p> <p>Furthermore, there's a helper for the lighting filter. The helper makes it a bit easier to determine where the light source is positioned and what parameters like <i>dz0</i> and <i>concentration</i> do.</p> <p> </p> <p><span class="media"><img src="/code/data/media/coreimage-layers52.jpg" height="520" width="751" /></span> </p> <p>With each filter you can use the <i>interface</i> parameter to get NodeBox sliders that control the options for the filter. It's a convenient way to get to know how each filter works.</p> <p><span class="media"><img src="/code/data/media/coreimage-layers53.jpg" height="551" width="739" /></span> </p> <p> </p> <p>Notice how each parameter you normally define in code is now replaced by a handy slider.</p> <p> </p> <hr /> <h2><a name="morguefile" title="morguefile"></a>Working with images from MorgueFile</h2> <p>The Core Image library includes a tool to download images from <a href="http://www.morguefile.com/">MorgueFile</a>. MorgueFile is an online archive of freely contributed photographs. To use MorgueFile images in NodeBox, you need to add the <i>morguefile.py</i> library to the folder where your script is located. You can then query MorgueFile and download images to a specified folder.</p> <p> </p> <p><span class="media"><img src="/code/data/media/coreimage-morguefile1.jpg" height="520" width="751" /></span> </p> <p>The <i>morguefile.search()</i> command returns a list of images on MorgueFile on the given query, It has an optional parameter <i>max</i> specifying the maximum number of images to return.</p> <pre class="python"><span style="color: #530035;">from</span> coreimage <span style="color: #530035;">import</span> morguefile
images = morguefile.<span style="">search</span><span style="">(</span><span style="color: #ff0080;">"leaf"</span>, <span style="">max</span>=<span style="">10</span><span style="">)</span></pre></pre> <p>Each item in the returned list has a number of properties:</p> <ul> <li><i>img</i>.id: the unique MorgueFile ID for the image</li> <li><i>img</i>.category: the category the image belongs to</li> <li><i>img</i>.author: the name of the author</li> <li><i>img</i>.name: the image's name</li> <li><i>img</i>.url: the URL of the image thumbnail</li> <li><i>img</i>.date: the date the image was added to MorgueFile</li> <li><i>img</i>.views: the number of times the image has been viewed</li> <li><i>img</i>.downloads: the number of times the image has been downloaded</li> </ul> <pre class="python"><span style="color: #530035;">for</span> img <span style="color: #530035;">in</span> images:
<span style="color: #530035;">print</span> img.<span style="">name</span>, img.<span style="">views</span>
>>> DSCN6707.<span style="">JPG</span> <span style="">8</span>
>>> keegan_2006_1015random0106.<span style="">JPG</span> <span style="">10</span>
>>> Img2006<span style="">-10</span><span style="">-08</span><span style="">-132310</span>.<span style="">jpg</span> <span style="">611</span>
>>> climb_a_tree_2006_1015random0086.<span style="">JPG</span> <span style="">17</span>
>>> missyredboots111.<span style="">jpg</span> <span style="">14</span>
>>> IMG_6852.<span style="">jpg</span> <span style="">403</span>
>>> Fallen_Star.<span style="">JPG</span> <span style="">25</span>
>>> JGS_mF_FloatingInDarkness.<span style="">jpg</span> <span style="">30</span>
>>> leaf_n.<span style="">JPG</span> <span style="">18</span>
>>> drift_away__.<span style="">jpg</span> <span style="">103</span></pre></pre> <p>You can use the <i>img.download()</i> method with any of these image objects. This command takes two optional parameters: <i>path</i> specifying in what folder to put the image (if the folder doesn't exist it will be created) and <i>thumbnail</i>, which when True downloads a small thumbnail instead of the image itself.</p> <p>The command returns the pathname of the image, which is the specified <i>path</i> + the name of the author + the name of the image.</p> <pre class="python"><span style="color: #530035;">print</span> images<span style="">[</span><span style="">0</span><span style="">]</span>.<span style="">download</span><span style="">(</span><span style="color: #ff0080;">"images"</span><span style="">)</span>
>>> images/dineshtilva_DSCN6707.<span style="">JPG</span></pre></pre> <p> </p> <p><span class="media"><img src="/code/data/media/coreimage-morguefile2.jpg" height="411" width="548" /></span> </p> <p>You can then start using the image as a canvas layer.</p> <p>There's also the <i>morguefile.search_by_author()</i> command which looks for images by author name.</p> <p> </p><hr /><h2><a name="dynamics" title="dynamics"></a> Working with dynamics and caching</h2><p>You can create a cached screenshot from a layer or a canvas. This means Core Image will render the layer or canvas with all its transformations, masks, adjustments and filters and return it as an object stored in memory instead of drawing it to the screen. You can then reuse that object as a layer in a canvas. This way you can incrementally <i>stack</i> effects in a fast animation.</p><p>The <i>layer.render()</i> and <i>canvas.flatten()</i> methods return a cached screenshot. You can pass this screenshot to the <i>canvas.append()</i> command. Then you can stack new effects on the transformed layer, take a screenshot of it, apply more filters to it, and so on.<br /></p><p> </p><table border="0"><tbody><tr><td><p><span class="image_border"><img src="/code/data/media/coreimage-dynamics1.jpg" alt="coreimage-dynamics1" /></span></p><br /><span class="image_border"><img src="/code/data/media/coreimage-dynamics2.jpg" alt="coreimage-dynamics2" /></span><br /></td><td><pre class="python"><span style="color: #530035;">speed</span><span style="">(</span><span style="">30</span><span style="">)</span>
<span style="color: #530035;">def</span> <span style='color:rgb(255,0,50)'>setup</span><span style="">(</span><span style="">)</span>:
<span style="color: #530035;">global</span> cache
cache = <span style="color: #530035;">None</span>
<span style="color: #530035;">def</span> <span style='color:rgb(255,0,50)'>draw</span><span style="">(</span><span style="">)</span>:
canvas = coreimage.<span style="">canvas</span><span style="">(</span><span style="color: #530035;">WIDTH</span>, <span style="color: #530035;">HEIGHT</span><span style="">)</span>
<span style="color: #530035;">global</span> cache
<span style="color: #530035;">if</span> <span style="color: #530035;">not</span> cache:
cache = canvas.<span style="">append</span><span style="">(</span><span style="color: #ff0080;">"leaf.jpg"</span><span style="">)</span>
<span style="color: #530035;">else</span>:
cache = cache.<span style="">render</span><span style="">(</span><span style="">)</span>
cache = canvas.<span style="">append</span><span style="">(</span>cache<span style="">)</span>
cache.<span style="">filter</span><span style="">(</span><span style="color: #ff0080;">"twirl"</span>,
radius=<span style="color: #530035;">random</span><span style="">(</span><span style="">30</span>,<span style="">40</span><span style="">)</span>,
dx=<span style="color: #530035;">random</span><span style="">(</span><span style="">-40</span>,<span style="">40</span><span style="">)</span>,
dy=<span style="color: #530035;">random</span><span style="">(</span><span style="">-40</span>,<span style="">40</span><span style="">)</span><span style="">)</span>
canvas.<span style="">draw</span><span style="">(</span><span style="">)</span></pre></pre></td></tr></tbody></table><p>Try out some other examples bundled in the library download. You may notice that incrementally applying filters and effects to layers makes them blurry.</p><p> </p> <hr /> <h2><a name="issues" title="issues"></a>Known issues and limitations</h2> <p>The library is currently in alpha stage and has some known issues and limitations:</p> <ul> <li><p>Exporting a PDF with a canvas that has a transparent background might contain pixel errors.</p></li> <li><p>Exporting a CMYK TIFF uses a Generic CMYK profile. This means that the canvas renderer makes no attempt to correctly remap colors that are outside the CMYK scope: pure RGB red and other high intensity colors may contain pixel errors. This is especially true for layers created from paths. It is your responsibility to create paths in CMYK-safe colors. Usually everything is OK so long as you use paths created with NodeBox <a href="/code/Reference_|_color()">color()</a> colors.</p></li> <li><p>Using the <i>layer.distort()</i> command in combination with layer filters displaces the layer from the origin, because the bounding box of a layer does not take filters into account. This means that the layer will no longer correctly display at the position you specified. An easy way to overcome this is to call <i>layer.filters_first(False)</i> to first render the distort and then apply the filter.</p></li> <li><p>Combining different filters might sometimes produce no output or crash NodeBox. If you are experiencing strange behaviour, try quitting and reopening NodeBox so the Core Image library has a chance to reload itself.</p></li> <li><p>Some filters are kinda quirky, especially the motion blur filter and perspective tile.</p></li> <li><p>If you rotate a canvas drawn in NodeBox using <i>transform(CORNER)</i> it rotates from the bottom left corner instead of the top left corner.</p></li><li>Core Image might run very slow or even halt NodeBox when exporting multiple PDF's or animations from a complex canvas. Exporting image files leaks memory as well (which can result in kernel panic). I haven't found a solution yet - there's a problem when calling <i>CIContext().drawImage</i>. For now, don't export movies/PDF's/images in batch (e.g. a thousand in one roll), or use an external screen capture tool like IShowU.<br /></li> </ul> <p> </p>
</div>
</div>
<div id="footer">
Last modified: Dec 10 2009 | © 2004-2012 <a href="http://www.emrg.be/" class="noexternal">Experimental Media Research Group</a>
</div>
<img src="/code/g/footer.jpg" style="border:0" class="footer" width="800" height="334" />
</div>
<script>
try{e=document.getElementsByTagName("span");for(i=0;i<e.length;i++){if(e[i].className=="header_image"){src=e[i].getElementsByTagName("img")[0].src;document.getElementById("header_image").src=src;break;}}}catch(e){}
</script>
</body>
</html>