When John Whitney made his pioneering computer art films as an artist in residence for ibm in 1960, the computer screen he used did not use pixels. Rather, it was a single beam which could be instructed to move across the screen, much in the same way that postscript instructions tell a vector to move.1
The graphics in Atari’s arcade games, like Battlezone, were also drawn with vector lines on an oscilloscope.2 In the long run, a matrix of points became the preferred method to describe screen output. And it still is today. In fact, we have a more rigid matrix now that we use lcd displays: they have a “native” resolution determined by the number of pixel elements — whereas the phosphor dots in a color crt display bear no relation to pixels or subpixels displayed on them.3
So, to get your digital resources out on a computer screen, you have to describe them as a matrix of points. That’s easiest when you work with data that itself is a matrix of points. It’s even easier when you map the matrix of points directly in the data to the matrix of the points on the screen.
The easiest solution is not the best, in this case. Try to browse the internet on a 24 inch screen and, by default, it will look rather awkward: singular columns of 960 pixels, with huge swaths of background image on either side. That is because the layouts are specified in CSS pixels and, by default, the browser makes them correspond with “device pixels”.4 Where this used to be a predicament, now it’s just a convention. All modern browsers support zooming in on the content. They're able to make pixel-based layouts smaller or bigger.
On the mobile phone, the rapport between the pixel of the design and the pixel of the screen has been cut entirely. The webpage is initially displayed fully, and subsequently the user can zoom, continuously, in and out on the design.
Scalable user interfaces benefit from vector graphics. After all, vector graphics are supposed to shine in the world of scalable.5 There's even a vector format that was named after this inherent property: Scalable Vector Graphics. But does that mean we can’t use the model of the bitmap in our new designs and interfaces? Not necessarily.
When in doubt, look at your predecessors. Most of our historic design for the computer screen is bitmap-based. I like to look at early pixel-based guis for inspiration. There’s a library of icons and user interface elements for the X window system, collected by Anthony Thyssen, available online.6 Because of the limitations inherent in early systems, many of them are really simple, black and white, 16x16 bitmaps. Through tight constraints, they attain a very evocative kind of abstraction. In this they resemble Susan Kare’s icon designs for the original Macintosh, which are much better executed than current iterations.
These designs don’t deserve to stay locked to the grid of display pixels growing ever tinier. They also don’t have to: you could paint these designs with square meter pixels on your wall, with even that rendering making them look great.
But what better way to reinterpret these designs than to convert them to vectors?
Traditional tracing algorithms do no justice to these designs. Looking for the curves underlying the designs ignores that the pixel grid is constitutive of the design. We are not looking for the platonic ideal. In this case, there's nothing to do but make vector pixels: a vector square for every pixel! It doesn’t even have to be a square. After all, a bitmap is a collection of points, and points have no predefined shapes. It could be circles or any arbitrary shape. You could make the pixels come together in horizontal scanlines, or vertical ones. You could distort the grid on which they are based.
There are many possibilities in the future of rendering and the further we go in exploring them, the closer we come to keeping alive the heritage of our pixels.
A city.A tornado (from Nethack).
When in doubt, look at your predecessors. Most of our historic design for the computer screen is bitmap-based.
Want to make your own vector pixels? Follow these (relatively easy) steps to generate your own vector pixel icons.
The following instructions should work just fine on either Linux or Mac.
Grab the code: Either type it in by hand, copying the code below or go to the assets section of our website and download the vector pixel pack we've prepared for you.
If you're copying out the code manually, enter it into a text editor and call the file
Find an image: If you're doing it on your own (instead of using the assets we've provided), find a simple image. Make sure it has very few colours (you're going to have to strip all the colour out of it). Simple logos, warning signs and similar types of images work well. Open it up in your favourite raster image editor (we used GIMP).
Strip out the colour by doing things like increasing the contrast as much as possible and posterizing. You're aiming to have an image with only black and white. While you're at it, resize the image to a very small size. 50px by 50px works well.
Warning! We're serious about the small image size. If it's too big, the resulting SVG will be very, very big and may just crash your image viewer.
Save your image (as something like a png, jpg or other basic raster format). Make sure to flatten while you're at it. Layers will only cause trouble in this case. Make sure you save it in the same directory as your vectorpixel.py file.
Point the script: Take another look at vectorpixel.py. On the 8th line, you'll find something that looks like this:
SOURCEIMAGE = 'city.png'. If you've made an image of your own, you'll want to change
city.png to whatever the name of your file is. Then save
vectorpixel.py again. Now, when you run it, it'll be looking for the right image.
Convert it: Open up your terminal (for more on using the terminal, check out the detailed instructions and explanation on pages 22-23). Navigate to the directory containing
vectorpixel.py and your image.
At the prompt, type:
python vectorpixel.py > city.svg
If you've provided your own image, you can change that last bit. For example, if your source file is called attention.png, you can sub in attention.svg. All this does is set up a destination file.
Hit enter. It'll look a little like nothing has happened. However, if you go and take a look in your folder, you'll find a new file, called
city.svg (or whatever you've named it). Take a look at it. It should be made up of lots of little vector pixels.
You've just made a vector pixel icon!
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
#!/usr/bin/env python """ Generates vectorpixels based on 2-bitmaps (2 color pictures). TODO: use element tree for XML; implement Floyd-Steinberg dithering for color and greyscale images; implement vertical and horiontal scanlines """ import Image SOURCEIMAGE = 'city.tiff' class vectorpixel: def __init__(self, image): self.i = Image.open(image) self.px = self.i.load() self.constructed = False def construct(self, grid=24, line=1, rounded=4, test=(lambda x: x == 0)): self.grid = grid self.line = line self.rounded = rounded self.width = self.height = self.grid - 2 * self.line self.test = test self.fill = '#000000' self.constructed = True def _yieldlocations(self): for x in range(self.i.size): for y in range(self.i.size): if self.test(self.px[x,y]): yield (x,y) def _mkelements(self): for l in self._yieldlocations(): yield "<rect x='%s' y='%s' width='%s' height='%s' rx='%s' fill='%s'/>" % ( self.grid * l + self.line, self.grid * l + self.line, self.width, self.height, self.rounded, self.fill) def _format(self): output = '<svg xmlns="http://www.w3.org/2000/svg" width="%s" height="%s">\n' % ( self.i.size * self.grid, self.i.size * self.grid) for e in self._mkelements(): output += e output += '\n' output += '</svg>' return output def generate(self): if not self.constructed: self.construct() return self._format() if __name__ == "__main__": v = vectorpixel(SOURCEIMAGE) print v.generate()
Eric Schrijver (Amsterdam, 1984) is a visual artist who makes installations and performances. Eric teaches Design for new media at the Royal Academy of Art in The Hague. He is inspired by open source and programming culture. http://ericschrijver.nl
Thanks to Joost Rekveld for his classes, introducing these works amongst others ↩
Form and Code, In Design Art and Architecture: Casey Reas, Chandler McWilliams, LUST; Princeton Architectural Press 2010 ↩
Actually, there are quite some pixel based scaling algorithms too: http://en.wikipedia.org/wiki/Pixel_art_scaling_algorithms ↩