Texture tiles
I've been wondering how to colorize Mark Meyer's parametric surfaces from an image. Since we can get pixel colors from an image using Core Image this is accomplished fairly easy. One problem is that at some point on the surface the edges of the image will meet, resulting in a "break" in the composition. To remedy this, we need a tileable image with a width and height equal to the n parameter in the parametric surface script.
I'll start out from an image of a car engine. To make it a little more interesting, I composited it with an image of some rust. It looks a bit more grungy and tangible that way - and its colors are more harmonious. The result is my starting image file, engine.jpg.
The trick to create a tile from the image is to take a portion of the image that is smaller and then wrap around the right and bottom parts. The Core Image library is excellent to automate this process.
Here's how we start out:

![]() | Flip right We create a duplicate of the layer and move it to the left, exactly so that the part that falls outside of the tile's bounding box ends up at the left. |
|
Gradient mask When we place two copies of the tile next to each other we want them to transition smoothly into each other. To do that, we add a linear gradient mask on the layer we shifted to the left. The layer's uttermost left edge will then be completely opaque (and it matches the right edge of the layer below). Then it will become more and more transparent and fade into the layer below. |
![]() | Merge and flip bottom We can now merge the two layers together and use the new layer to flip the bottom to the top. The result is a tile that matches on all sides. Now that you know how the principle works I might as well just add the Core Image script. It will save you some work fiddling with layer positions. |
img = "engine.jpg" coreimage = ximport("coreimage") def tile(img, w=350, h=350): """ Returns a tileable canvas of given width and height. """ # Create a canvas from the image. # The canvas will have the same size as the image. canvas = coreimage.canvas(img) l = canvas.append(img) # Place the top left corner of the image # in the top left of the canvas. # We'll "wrap around" the overflow on the right and bottom. l.origin_top_left() l.x = 0 l.y = 0 # Create a duplicate, shift it to the left # so only the overflow on the right is visible. wrap = l.duplicate() wrap.x = -w # Add a horizontal linear gradient mask to the wrap. # It should gradually disappear revealing the original image. m = wrap.mask.gradient() m.scale(1.0, int(l.width-w)) m.rotate(-90) m.origin_top_left() m.x = w m.y = l.height # We now have a composition that is horizontally tileable. # We'll flatten our work to a single layer which we can # then wrap vertically. merged = canvas.flatten() canvas[0].hidden = True canvas[




