mga/blog

ISSN 2011-0146

From Paper Maps to the Web: A DIY Digital Maps Primer

publicado en arte,diseño,interacción,programación,tips,web por mga en January 8, 2015

Este post fue publicado inicialmente en los blogs de NYPL. Versión en español pronto.

I was invited to the National Library of Colombia’s 2nd Digital Book Week as a speaker and to give a workshop on digital mapping tools. I thought it would be useful to share that workshop since it encompasses a lot of different processes and tools that make digital cartography today very accessible. It is a primer on working with various free web mapping tools so you can make your own awesome maps.

TL;DR

You will make this. This tutorial assumes you have a digitized map and some data you want to overlay on it. The general steps covered are:

  1. geo-referencing the scanned map so that web tiles can be generated
  2. generating GeoJSON data to be overlaid
  3. creating a custom base map (to serve as reference/present day)
  4. integrating all assets in an interactive web page

Note: This tutorial assumes you are using Mozilla Firefox, Apple Safari or Google Chrome. You will be playing with the developer console and I don’t have multi-browser instructions.

Let’s get started!

This is what we want to make. It is an 1891 map of Bogotá available in the National Library of Colombia (link requires Flash Player) annotated with some data found in an 1888 Bogotá City Directory.

1) Geo-referencing

The first step after scanning a map is to add geographical data to it; to establish an equivalence between its pixels and the geographic location they represent. This is called geo-referencing. This process will distort the scanned image:

Original scan
Original scan (shrunk, of course)

…to match the Mercator projection which is used in most web mapping projects such as OpenStreetMap or Google Maps:

Geo-referenced scan in Mercator projection
Geo-referenced scan in Mercator projection

The amount of distortion will depend on the quality of the survey, preservation state and original projection of the map. You may be asking: how did this magically happen? There’s commercial and open-source software that allows you to geo-reference images but the point of this tutorial is doing all of this without installing any software other than your web browser. Enter: The Map Warper! Map Warper is a web tool that lets you upload your scanned maps and provides a simple interface for you to geo-reference them (or “rectify” in geo parlance). Referencing boils down to you telling what part of the scanned map (left) corresponds to what part of the Mercator projection (right):

Map Warper
The split-view rectification interface in Map Warper

Notice the pins in the image. Each pin has a number and the same pin is present in both views. From them you can tell that North in the scan is pointing leftwards while East is pointing upwards. The more pins you add, the more precise the referencing will be but the slower the final image generation. However, image generation happens only once so I wouldn’t worry too much about that. It’s more an issue of how many pins you are willing to add. The map in this tutorial has 101 pins.

A final consideration in this process is to make sure you get a high-quality geo-referenced image after distortion. The process of distorting the original image is called resampling 1. In the Map Warper’s Advanced options you can set the method from the low-quality but fast Nearest Neighbour to high-quality but slow Cubic Spline:

Resampling method selection
Select “Cubic Spline” in the Resampling Method option

You can view the final map here. You can also download high-resolution assets in the Export tab. However, I think the main perk you get from the Map Warper are the tiles. It’s that URL template you see here:

Map Warper
You can find the tile URL in the “Export” tab

The template is:

http://mapwarper.net/maps/tile/4949/{z}/{x}/{y}.png

You will need this URL! Keep it somewhere safe. Map Warper has a tile-generating engine that uses the geo-referenced image to produce square map tiles at different zoom levels and coordinates so that only the necessary parts of the interactive map get displayed as you use it2. This is an example tile:

a web map tile
Web maps are made up of millions of these

2) Data extraction

We have the map. Now we want to figure out what data to show on it. Our example uses this 1888 City Directory of Bogotá, Colombia’s capital city. This directory is information-rich, containing tens of thousands of person names (each with address and occupation), dozens of different occupations (described in page 4) and advertisements (along with many store addresses and owner names).

The directory provides an interesting view of life in late XIX century Colombia: lawyers, photographers and accountants share pages with saddlers and blacksmiths. I went the boring route and looked for some prominent politicians of the time, such as then-sitting president (page 222, first in the second column). The current list contains seven people: four presidents, a vice-president, a minister and an acting president3. The list includes:

  • name
  • office (highest office held in the Colombian executive branch)
  • term
  • page (where it appears in the directory)
  • occupation (as displayed in the directory)
  • address
  • Wikimedia Commons photo URL
  • latitude, longitude (a placeholder set to downtown Bogotá that we will change in this step)

Download the CSV list

You can create your own list from other data you find more interesting or useful. Make sure to include latitude and longitude columns and save it as a comma-separated list.

GeoJSON

So far our data is contained in a comma-separated list, but web mapping tools generally use the GeoJSON standard. GeoJSON is based on JSON which is one of the most popular ways of structuring data in the web. GeoJSON uses the concept of “features” to describe geographic data. Those features can be points (as is our current case) or more complex geometries such as lines, multilines and polygons. Each feature is described by its geometry (the point, line, polygon itself) accompanied by its properties which is whatever extra data you want to associate with it (in our case, a person’s name, address, photo, etc.). For example4:

We need to convert our spreadsheet into a GeoJSON object and then update the placeholder latitude and longitude values to the proper values. We will use the map itself to help us figure out those. We need a tool that lets us generate GeoJSON that we can easily manipulate.

Enter GeoJSON.io! This is “a quick, simple tool for creating, viewing, and sharing maps”. GeoJSON.io has this nifty interface we can use to create the GeoJSON we need.

Go ahead and open GeoJSON.io in a new browser window. you will see the default map at full zoom out. Now we need to do a little hacking. Right-click somewhere on the map and select Inspect Element:

Right-Click -> Inspect Element
Right-Click ? Inspect Element

This opens an advanced developer view that let’s you view and modify the code of the page you are viewing (in this case, the map interface). GeoJSON.io includes a programming interface (API) that lets you control the map being displayed. The core of this site is MapBoxJS, which is itself built on top of Leaflet, an “Open-Source JavaScript Library for Mobile-Friendly Interactive Maps”. I mention both because, for the most part, whatever works on one of them works on the other (do read the documentation before making any decisions!) and I will be referring to it as Leaflet instead of MapBoxJS.

In the Console tab you’ll see some text and, at the bottom, a cursor where you can execute JavaScript code. You’ll see some comments from the creator of GeoJSON.io and a row where you can type new JavaScript commands. Type this in that area and press ENTER (refer to the animated GIF below):

This will center and zoom the map in Bogotá, Colombia, the area covered by the 1891 map. Now type this:

…and press ENTER. This will add the tile layer itself. Notice that line of code includes the URL you copied in step 1. The end result will look something like this:

Before and after executing the commands
A quick “hacking” of GeoJSON.io

You can now close the development window (not the browser window!).

Note: You will need to re-apply this code every time you load GeoJSON.io since it doesn’t save modifications made via console. You can save the data you add to the map by logging in.

Adding data to GeoJSON.io

Now we will use this modified version of the map as a base to properly geo-locate the CSV list of presidents.

Drag the CSV file you downloaded on the map:

drag and drop magic
Drag and drop magic in GeoJSON.io

You will notice how the data is immediately converted to GeoJSON (right pane) and the map zooms in to show the points that represent each president (left pane). You can see a small green message (top left) showing seven features were imported.

But the 1891 map disappears! No worries. This just means that the map is zoomed in “too close to the ground” and the tile URL template does not have images up to that level. Zoom out a bit and you will see the 1891 map appear again.

Moving the points around

The points in the CSV are all geo-located on top of each other on the same point in Bogotá’s Plaza de Bolívar. We need to move them to their proper location. If you click the gray pin you will see the additional data for the topmost one (General Rafael Reyes). His address at the time was 50, Calle 16 (50 16th Street). We need to find that address in the map.

Finding the address will be relatively easy since each block has its starting and ending address numbers written on the corners. You will notice that “Carrera” (vertical-ish streets) numbers increase northward with odd numbers east and even numbers west while “Calle” (horizontal-ish streets) numbers increase westward with odd numbers south and even numbers north:

Address numbers

We will place the point in the approximate location between corners in a given block. To do so, activate editing mode by clicking the Edit icon icon. Pins will have a pink outline and you can move them around. Place the pins in the desired location and click “Save” to commit the changes:

Moving points around

There are some tricky addresses but this task can be quite enjoyable since you literally get lost in 1891 Bogotá. An interesting aspect of this map is that government buildings are colored with the Colombian flag. When you place Rafael Núñez Moledo, the sitting president at the time, you will notice that his address matches one of those flag-colored buildings (the Casa de Nariño).

Saving the GeoJSON

Now we must generate the final GeoJSON that we will use to create our interactive map. Simply select Save > GeoJSON in the editor menu. A file called map.geojson will be generated and downloaded to your computer. You can also just download the one I did, cheater!

3) Creating a 2014 custom map (optional)

We want to be able to compare this 1891 map with present day Bogotá so we can see how things have changed over time. We need a “base map” which is basically what GeoJSON.io has when you load it: a (hopefully accurate) “plain vanilla” street map of the present day world. You could use the standard OpenStreetMap tiles or use a service such as MapBox to produce a completely custom map (MapBox uses OSM data). MapBox is quite powerful: it lets you change colors, customize what gets shown (streets, buildings, parks, etc.) and even use satellite imagery!

I’m not going to describe how to create your own map in MapBox. I will leave that to their excellent tutorial. When you’re done, you will need to write down the Map ID which looks something like username.k53dp4io. You can use the MapBox projects page to see all your maps and easily copy the ID to clipboard:

MapBox Map ID

NOTE: If you don’t want to go through the process of customizing your map, you can use an example MapBox ID later.

4) Final assembly

We now have all the assets required to assemble our interactive map:

  • map data in GeoJSON format
  • a tile template for the 1891 map
  • a tile template or MapBox ID for the 2014 map

We will prototype the interactive map in JSFiddle, a tool that lets you quickly create and test HTML/JavaScript/CSS code. Check out this quick tutorial to familiarize yourself with the interface.

JSFiddle has four main panes:

  • HTML code (top left)
  • CSS code (top right)
  • JavaScript code (bottom left)
  • The end result (bottom right)

JSFiddle takes care of assembling the three code components into the result every time you click “Run” (in top, blue bar).

HTML & CSS

In this example the HTML and CSS parts are very simple. We only need a rectangular area in the page that will display the map and all its controls.

We need an HTML element where the map will go. Type or copy/paste this in the HTML pane:

With this code we create a div element whose identifier is map and, as you can imagine, it will contain the map. We now need to “style” the element (give it a width and a height and, if you want to, borders and other attributes). Styling is controlled with CSS. Type or copy/paste this in the CSS pane:

This applies a width and a height of 400 pixels to the element whose identifier is map (the # prefix means “id” in CSS). Of course you can make the rectangle bigger (if your monitor is big enough) and apply other attributes between those { } brackets (e.g.: background-color: #f00; for a red background if you want to see the element with no map) but I just wanted to keep it very simple.

If you click “Run” now you won’t see much (unless you added a background color or a border to the element). That’s all the HTML and CSS you will need for now.

Adding MapBoxJS

To present the map and make it interactive we will need some external assets and JavaScript. I mentioned Leaflet and MapBoxJS before. We are going to need them in order to present and control the map. Leaflet is included in MapBoxJS so we just need to worry about the latter. MapBoxJS is composed of two separate files: a JS file and a CSS file. You already have an idea of what the CSS file does. The JavaScript file contains all the interactive mapping magic. These are the URLs to the files in question (note that it is not the latest MapBoxJS version but no worries, it will work):

CSS file:

http://api.tiles.mapbox.com/mapbox.js/v1.5.0/mapbox.css

JavaScript file:

http://api.tiles.mapbox.com/mapbox.js/v1.5.0/mapbox.js

In the left column in JSFiddle find the “External Resources” section. You need to copy those URLs and paste each in the JavaScript/CSS URI box and click the + button. You will see something like this after you do it:

jQuery in JSFiddle
Your “fiddle” once you add the two MapBoxJS files

This will make JSFiddle load those files the next time you click “Run” and from then on.

Hello map!

Now comes the part we’ve been waiting for! Let’s write some JavaScript so we can see the 1891 map. Write this in the JavaScript pane:

…and click “Run”. This is what you should see:

Hello map
You first web map!

Thanks to Leaflet, it’s that easy to work with web maps.

Note: I’m not going into details here about the different aspects of the Leaflet or MapBoxJS APIs. They each have their own tutorials and examples. I will instead give some code snippets and superficially explain what they do. You will copy, paste and click “Run” and magic will happen5. You will later figure out how to do more awesome things on your own.

Managing multiple tile sets

You may notice that the map is all white except for the 1891 map and that is good. The tile set URL only has the rectified map on it and nothing else. We need to have an additional 2014 tile set to compare (I will use an example MapBox Map ID, in case you did not create your own in step 3 above). We will replace the JS code with new one that will contain:

  • some attribution information for the map (useful for when you want to, you know, attribute data in the map)
  • the 2014 tile set
  • a control that will let us swap one tile set for another

This code should replace your previous JS:

If you look throught this code you will notice it is quite similar to what we had before. The main differences are the addition of attributions and MapBox tile sets (via the map ID). The control itself is two lines: one to create a baseMaps variable that will hold the tile sets (you can add as many tile sets as you want) and another to create the control and add it to the map. Behold the control in action:

Tile set magic
Notice how the attribution changes when you toggle the tile sets

We’re almost there! We now need to display our data. Leaflet makes this process quite easy since it natively supports GeoJSON. The process is just a few lines, but first remove the map zoom function map.setView([4.598056, -74.075833],14). Now paste this code at the bottom of the JS pane:

You need to copy the GeoJSON output from the text file you downloaded from GeoJSON.io and paste it where you see 'paste_geojson_here_keep_quotes'. Make sure you keep those quotes! That line should end up looking something like:

We replaced the zoom function with map.fitBounds(geolayer.getBounds()). This makes the map “smarter”: instead of us typing longitude, latitude and zoom level by hand we let Leaflet calculate the bounding area for the set of points provided with getBounds() and pass that as a value to the map’s fitBounds() function. Voilá, the map now zooms to show all the points in the set. If you add more points the bounds will change automatically!

You can also add the points and any other data overlay to the layer toggler. You just need to create a variable similar to the one you created for the tile sets and update the control creation code:

You will see something like this when you click “Run”:

Hello pins
Your map with custom data on it

Note: Make sure to move the control creation code L.control.layers to a point below where the GeoJSON is being parsed. The geolayer variable needs to exist for it to be added to the overlays. Refer to my JSFiddle result for details.

Another important line is the one with the L.geoJson() function. This function parses all the features described by the map.geojson. Leaflet/MapBoxJS have default blue pin icons for point features which you can customize if you want. L.geoJson() will also let us add some interaction to the pins. Right now clicking them does nothing.

Making the pins come alive

We want to click on the pins and show a popup box with the data we have associated to it (in the feature’s properties). We need to do two things:

  1. a function that will build and present the popup for a given feature (point)
  2. modify the L.geoJson() call to use this function

Leaflet’s bindPopup() layer function does just that: draws a box with text next to a given layer. This text can be marked up with HTML. Copy/paste this code below all you have so far:

This showPopup() function receives a feature, the piece of GeoJSON that contains all the information (geometry and properties), and a layer, the same GeoJSON as displayed by Leaflet (in our case, the blue pin). These two parameters are passed automatically by the L.geoJson() function. showPopup() then loops through each property in the feature (name, address, etc.) and builds an HTML string. This string is used as the markup for the popup.

We have not connected showPopup to anything. Modify your current L.geoJson line as follows:

…you are just adding , {onEachFeature: showPopup} after geodata. This tells Leaflet to apply the showPopup function for each feature in the GeoJSON.

Note: If your GeoJSON contains multiple types of features (e.g.: points, lines and polygons) you need to keep in mind the same function will be applied to all of them. For example, polygons have bounds but points do not. You will need to check to see if the feature being clicked has bounds before trying to fitBounds the map.

Running the map and clicking on a pin will result in something like this:

A popup!

This is nice and all but wouldn’t it be better to actually see the photo and maybe link that page number to the directory itself? Let’s do just that! Replace the showPopup function with this one:

We just added a check in the loop: if key equals “Page” we build a link to the directory and if key equals “Photo” we build an image tag and constrain the height to 150 pixels (just in case the image is too big).

This is how Mr. Núñez looks like now:

Rafael Núñez bio

…worthy of a president!

And we’re done!

Wrapping it all up

You will want to compile these three code snippets in an HTML page to publish your new map somewhere. Worry not, below is a code snippet that has the requisite spots for you to paste CSS, HTML and JS. Save all the code as a .html file and publish it somewhere:

You can see the finished map here. I made minor modifications to the CSS to fill the browser window.

Hope you found this tutorial useful. Drop me a line if you have any comments or questions!


  1. Similar to what happens with music when converted from CD quality to MP3.
  2. Read this explanation for a better introduction on how web map tiles work.
  3. I did not thoroughly research the names in question so it may be (however unlikely) that they are homonyms.
  4. From GeoJSON.org
  5. Everything should work this way!

Generative ebook covers

publicado en general,programación,tipografí­a,visualización por mga en October 10, 2014

Este post fue publicado inicialmente en los blogs de NYPL. Versión en español pronto.

header

Finding better covers for public domain ebooks

Here at NYPL Labs we’re working on an ebook-borrowing and reading app. On the technical side, Leonard Richardson is doing all the back end magic, consolidating multiple data sources for each book into a single concise format: title, author, book cover and description. John Nowak is writing the code of the app itself (that you will be able to download to your phone). I am doing the design (and writing blog posts). Many of the ebooks we will be offering come from public domain sites such as Project Gutenberg. If you spend a few minutes browsing that site you will notice that many of its ebooks either have a really crappy cover image or none at all:

PG cover PG cover PG cover

Book covers weren’t a big deal until the 20th century, but now they’re how people first interact with a book, so not having one really puts a book at a disadvantage. They are problematic, and not only in ebooks. It’s difficult to find high-quality, reusable covers of out-of-print or public domain books. There are some projects such as Recovering the Classics that approach this problem in interesting ways. However, we at NYPL are still left with very limited (and expensive) solutions to this problem.

Given that the app’s visual quality is highly dependant on ebook cover quality (a wall of bad book covers makes the whole app look bad) we had to have a solution for displaying ebooks with no cover or a bad cover. The easy answer in this situation is doing what retail websites do for products with no associated image: display a generic image.

iTunes no cover S&S no cover Abrams no cover

This is not a very elegant solution. When dealing with books, it seems lazy to have a “nothing to see here” image. We will have at least a title and an author to work with. The next obvious choice is to make a generic cover that incorporates the book’s title and author. This is also a common choice in software such as iBooks:

iBooks cover

Skeuomorphism aside, it is a decent book cover. However, it feels a bit cheesy and I wanted something more in line with the rest of the design of the app (a design which I am leaving for a future post). We need a design that can display very long titles (up to 80 characters) but that would also look good with short ones (two or three characters); it should allow for one credited author, multiple authors or none at all. I decided on a more plain and generic cover image:

NYPL cover 1

Needless to say this didn’t impress anyone; which is OK because the point was not to impress; we needed a cover that displayed author and title information and was legible to most people and this checked every box… but… at the same time… wouldn’t it be cool if

10 PRINT “BOOK COVER”

While discussing options for doing a better generative cover I remembered 10 PRINT, a generative-art project and book led by Casey Reas that explores one line of Commodore 64 (C64) code:

10 PRINT CHR$(205.5+RND(1)); : GOTO 10

This code draws one of two possible characters (diagonal up or diagonal down) on the screen at random, over and over again. The C64 screen can show up to 40 characters in a row. The end result is a maze-like graphic like the one seen in this video:

At the 2012 Eyeo festival, Casey Reas talked about this project, which involves nine other authors who are collected in this book. I highly recommend watching Reas’s presentation (link jumps to 30:11 when 10 PRINT is mentioned). The two characters–diagonal up and diagonal down–come from the C64 PETSCII character list which is laid out here on the Commodore keyboard:

PETSCII

Each key on the PETSCII keyboard has a geometric shape associated with it. These shapes can be used to generate primitive graphics in the C64 operating system. For example, here is a rounded rectangle (I added some space to make it easier to see each character):

5 3 3 3 9

2 0 0 0 2

2 0 0 0 2

a 3 3 3 b

In terms of the letters on the same keyboard, that rectangle looks like this:

UCCCI
B   B
B   B
JCCCK

10 PRINT was the starting point for my next ebook cover generator. In 10 PRINT a non-alphanumeric character is chosen by a random “coin toss” and displayed as a graphic. In my cover generator, a book’s title is transformed into a graphic. Each letter A-Z and digit 0-9 is replaced with its PETSCII graphic equivalent (e.g. the W gets replaced with an empty circle). I used Processing to quickly create sketches that allowed for some parameter control such as line thickness and grid size. For characters not on the PETSCII “keyboard” (such as accented Latin letters or Chinese characters) I chose a replacement graphic based on the output of passing the character into Processing’s int() function.

Colors and fonts

In order to have a variety of colors across the books, I decided to use the combined length of the book title and the author’s name as a seed number, and use that seed to generate a color. This color and its complimentary are used for drawing the shapes. Processing has a few functions that let you easily create colors. I used the HSL color space which facilitates generating complimentary colors (each color, or hue in HSL parlance, is located in a point on a circle, its complementary is the diametrically opposite point). The gist code:

This results in something like:

hsl

To ensure legibility and avoid clashes with the generated colors, I always use black on white for text. I chose Avenir Next as the font. The app as a whole uses that font for its interface, it’s already installed on the OS and it contains glyphs for multiple languages.

There are more (and better) ways to create colors using code. I didn’t really go down the rabbit hole here but if you feel so inclined, take a look at Herman Tulleken’s work with procedural color palettes, Rob Simmon’s extensive work on color, or this cool post on emulating iTunes 11’s album cover color extractor.

Shapes

I created a function that draws graphic alternate characters for the letters A-Z and the digits 0-9. I decided to simplify a few graphics to more basic shapes: the PETSCII club (X) became three dots, and the spade (A) became a triangle.

I wrote a function that draws a shape given a character k, a position x,y and a size s. Here you can see the code for drawing the graphics for the letter Q (a filled circle) and the letter W (an open circle).

My cover generator calls drawShape repeatedly for each character in a book’s title. The size of the shape is controlled by the length of the title: the longer the title, the smaller the shape.

Each letter in the title is replaced by a graphic and repeated as many times as it can fit in the space allotted. The resulting grid is a sort of visualization of the title; an alternate alphabet. In the example below, the M in “Macbeth” is replaced by a diagonal downwards stroke (the same character used to great effect in 10 PRINT). The A is replaced by a triangle (rather than the club found on the PETSCII keyboard). The C becomes a horizontal line offset from the top, the B a vertical line offset from the left, and so on. Since the title is short, the grid is large, and the full title is not visible, but you get the idea:

10 PRINT "BOOK COVER"

There is a Git repository for this cover generator you can play with.

Some more examples (notice how “Moby Dick”, nine characters including the space, does fit in the 3×3 grid below and how the M in “Max” is repeated):

Macbeth

MOB
Y D
ICK

Max

MA
XM

And so on:

Douglass Aesop

The original design featured the cover on a white (or very light) background. This proved problematic, as the text could be dissociated from the artwork, so we went for a more “enclosed” version (I especially like how the Ruzhen Li cover turned out!):

Doctorow Li Justice

We initially thought about generating all these images and putting them on a server along with the ebooks themselves, but 1) it is an inefficient use of network resources since we needed several different sizes and resolutions and 2) when converted to PNG the covers lose a lot of their quality. I ended up producing an Objective-C version of this code (Git repo) that will run on the device and generate a cover on-the-fly when no cover is available. The Obj-C version subclasses UIView and can be used as a fancy-ish “no cover found” replacement.

Cover, illustrated

Of course, these covers do not reflect the content of the book. You can’t get an idea of what the book is about by looking at the cover. However, Leonard brought up the fact that many Project Gutenberg books, such as this one, include illustrations embedded as JPG or PNG files. We decided to use those images, when they are available, as a starting point for a generated cover. Our idea is to generate one cover for each illustration in a book and let people decide which cover is best using a simple web interface.

I tried a very basic first pass using Python (which I later abandoned for Processing):

Sherlock

This lacks personality and becomes problematic as titles get longer. I then ran into Chris Marker and Jason Simon’s work, and was inspired:

Marker & Simon

I liked the desaturated color and emphasis on faces. Faces can be automatically detected in images using computer-vision algorithms, and some of those are included in OpenCV, an open-source library that can be used in Processing. Here’s my first attempt in the style of Marker and Simon, with and without face detection added:

no cv cv

I also tried variations on the design, adding or removing elements, and inverting the colors:

no cv line cv line no cv inverted

Since Leonard and I couldn’t agree on which variation was best, we decided to create a survey and let the people decide (I am not a fan of this approach, which can easily become a 41 shades of blue situation but I also didn’t have a compelling case for either version). The clear winner was, to my surprise, using inverted colors and no face detection:

flatland ten girls procopius

The final Processing sketch (Git repo) has many more parameters than the 10 PRINT generator:

Image Cover P5

Conclusion

As with many subjects, you can go really deep down the rabbit hole when it comes to creating the perfect automated book cover. What if we detect illustrations vs. photographs and produce a different style for each? What about detecting where the main image is so we can crop it better? What if we do some OCR on the images to automatically exclude text-heavy images which will probably not work as covers?

This can become a never-ending project and we have an app to ship. This is good enough for now. Of course, you are welcome to play with and improve on it:

BodyType v0.1

publicado en arte,diseño,interacción,kinect,programación,tipografí­a por mga en March 4, 2012

Create fonts by waving in thin air!

I have finally found some time to build a semi-standalone binary (Mac OS X 10.6 or better) of BodyType, my Kinect-based font creation software. This version supports only UPPERCASE A-Z and 0-9. If you want to create more glyphs, let me know. The download includes a README.txt file that, as its name indicates, you must read. BodyType v0.1 is dependent in other libraries and programs in order to create your fonts properly and that file explains how to install them. They all should be installed with MacPorts.

The code is also available for download in Google Code.

Acknowledgements

This project was done as part of the requirements to complete the Spring 2011 Interactive Art and Computational Design course with Professor Golan Levin in Carnegie Mellon University.

BodyType was built with openFrameworks and makes use of ImageMagick, FontForge and Potrace.

Presentando Stereogranimator

publicado en arte,diseño,historia,interacción,programación,web por mga en January 26, 2012

GIF made with the NYPL Labs Stereogranimator - view more at http://stereo.nypl.org/gallery/index
GIF made with the NYPL Labs Stereogranimator

Publico esta foto hecha con el Stereogranimator como abrebocas para un post que publicaré más adelante sobre mi trabajo en la Biblioteca Pública de New York.

detalles coquetos

publicado en diseño,interacción,web por mga en January 22, 2012

Leyendo un post comentando sobre la compra de Summify por parte de Twitter llego al sitio web del primero:

Summify

Notarán el video que se insinúa arriba. No es un error. Ese detalle motiva a “buscar” el video, ya sea haciendo scroll vertical (que no funciona, pero sería elegante que sí) o dando clic en play. Al dar clic aparece el video:

Me pareció una curiosa forma de “mostrar el video sin mostrarlo” sacando provecho de la tendecia que tenemos a completar las formas.

siguiente página »