Saturday, September 4, 2010

Scalable Graphics

This week has been quite busy in the iDev world as on September 1st Apple held its yearly musical event where it presented the renewed iPod line.  And as expected by many the iTouch... I mean the iPod touch have been upgraded to the latest retina display, the same that can be found in the iPhone 4 released at the beginning of the summer.  What does it mean for us iDeveloper? Well yet again another screen resolution to support, as if you still want to support previous generation of iDevices (iPod touch 2nd/3rd gen, iPhone 3G, iPhone 3GS) and the newly iPad which are of different screen resolution then the iDevices using the newer retina display.

Let make a little recap in a small table of the different screen resolution we have so far.


Screen Resolution

iPod touch (2nd/3rd gen)
320x480 (@ 163 ppi)
iPhone (3G/3GS)
320x480 (@ 163 ppi)
1024x768 (@ 132 ppi)
iPhone 4
960x640 (@ 326 ppi)
iPod touch (4th gen)
960x640 (@ 326 ppi)

As you can see above this is 3 different screen resolution to support if you decide to support iDevices that will run iOS 4.x.  So unless you make a decision to support only the iPad or the new retina display, this is 3 set of graphics assets to generate.  Here is the few option that is available to you to deal with this situation :

  • Create from scratch pixel by pixel the graphic asset for each screen resolution.  Some artist will tell you this is the way to go as they can really optimize each graphic asset for the specific screen resolution.  This is true, but it probably gonna take much more longer to create them and be more costly (especially if you out source your graphics to an artist).
  • Create the graphic asset in a higher screen resolution and scale it down.  By doing this, you are only creating the graphic once and by the click of a button you generate the smaller screen resolution version.  This can be quite fast and easy to do, but results will vary greatly (depending on the graphic and tools/algorithm use to scale).  They are tools such as Genuine Fractals a Photoshop plug in from onOneSoftware that seem to do an excellent jobs, so you might want to try it, but as they say YMMV (Your Millage May Vary).
  • Create scalable graphics which will let you up/down scale them.  This will probably be the most effective solution for most of us, but how do you get scalable graphics?  By using a vector drawing program of course!  This way the graphic you're generating will be totally screen resolution independent,  which will allows you to scale them for any current or future iDevices such as the iPod Nano (did I just say that? Well look at the nano it has multi-touch screen now, UI look strangely familiar... and hey my cell phone have less resolution and it can play game made in J2ME) or AppleTV (hmmm using a familiar chip... A4?).  No I don't have any inside, it just that I've got that feeling that sometime next year they will be newer devices for us to play with ;-).  Also the iPad might also get a newer display when it get refresh later in 2011.
Honestly my first solution for my current game project iQBR1 was to use the solution #2, by creating the graphic asset in a higher resolution then needed in GIMP (and no this is not the devil as falsely reported by @gavinbowman).  Most of the scale down look ok, but I wasn't totally satisfied with the results.  So I decided to take a look at what can be done with a vector tool program and as reported in my previous blog entry "The Indie Software Toolbox" the tool that I had chosen was Inkscape (I also notice last night that the new version 0.48 just came out last week with new enhance feature).  But they are still a misconception that vector graphic are only good for simple clip art, charts and other geometrical shape/design, well think again...

As you can see we're not in Kansas anymore...  Of course making the graphic above will need time and skills but they are doable with a vector drawing program like Inkscape.  Now let see how to get your started with this on your iDev machine (I assume you have a Mac running OSX).

  • X11 (yes Inkscape was made for UNIX platform, to be more precise it was done on Linux), I would recommend you to install the latest version of xQuartz.
  • Inkscape of course, you can grab the lastest Snow Leopard OSX package installer here.
  • Fast Mac!  As this is a vector program it tend to use a lot of complex mathematics to generate graphics.  On my Mac Mini with only a Core2duo 1.83ghz it can become slow after applying a few layers of filter.  I am not sure if it support GPU, the latest version added support for multi-threaded Gaussian filter to speed thing up.
Once you've got everything setup you simply launch Inkscape which will then automatically launch X11.  You should then get something that look like this (note I did re-size the window and change the View->Zoom and set it to Zoom 1:1) :

In the following steps ill show you how you can create an interesting looking stone tile.  We will first create the background layer by first clicking the Layer->Layers... (or if your prefer shortcut Shift-Ctrl-L).  Then select Layer 1 (by default in a new document it create a layer with the name layer 1) and rename it to background.

Once this is done we will fill the background with black, to do this we will simply create a large black rectangle.  To do this first click the black colour in the bottom (this will set the fill colour), then select the square tools on the left.  Then drag around the rectangle to get it the size you want, take note that you can either have sharp edge or round edge.  To change this, simply click the second round circle (the one on the right) around the selected rectangle and drag it up/down until you have the desire shape for the edge.

We then proceed to the creation of our second layer by clicking Layer->Add layer... (alternatively you can achieve this by using the shortcut Shift-Ctrl-N or clicking the [+] button in the layer pane on the right side).  Now you create a square as describe in the previous steps, but this time we will choose an olive color (#808000) to draw it and also make it with round edges.

Now that we have our basic shape, we will apply a series of filters that will give a texture to it and make it look more 3d (so it doesn't look too flat).  The first filter we gonna apply is the Ridged border that you can access by going to the Filters->Bevels menu.  Then you select the second filter by clicking Filters->Bevels->Glowing metal, after this you should get something that have a nice 3d look.

We could have stop here, but since we also want to have a bit more texture to our stone tile let add a few more filters.  The third filter we gonna use is Marble 3D found in the Filters->Materials menu which will give us as the name says a marble texture to our stone tile.  Since we also want the stone tile to be a bit more rough on the edge then we apply our fourth filter by clicking Filters->ABCs->Roughen.

You may have notice that with the last filters we have lost a bit the more pronounce bevel effect.  To get it back we simply apply the Glowing metal filters from the Filters->Bevels menu once again (this is our fifth filter).  Then to add more relief to our marble texture we apply the sixth filter by clicking Filters->Bumps->Thick paint.

Now to add a few extra filters to give it the final touch.  Our seventh filter will be to re-apply the Ridged border from the Filters->Bevels menu.  Then we gonna make the edge a bit more rough by clicking Filters->Distort->Torn edges as our eighth filter.  And finally by applying a little feathering around the edges by clicking Filters->ABCs->Feather. 

Here you go, you have completed your first stone tile.  Now you can re-size it by simply dragging the bottom right square handle or the top left square handle.  Once you're satisfy with the result you first save your file into SVG (this is the open standard for storing vector graphics, if you open up the file you will see its simply an XML file with all the data and commands to recreate your graphics).  Sadly iOS doesn't recognize this format directly for displaying UIImage (even though that Safari and UIWebView support it), so you will need to export it into a bitmap preferably in PNG.  To do this you simply need to click on File->Export Bitmap... (or by using the shortcut Shift-Ctrl-E) which will pop up a window where you can set different parameters of the export (area, bitmap size, filename).  So now its just a matter of re-sizing your graphic asset to the resolution you need either by scaling them inside Inkscape or specifying the size in the export.

Here is the result of the same image exported in different resolution/size.


Original (size created in Inkscape)

Large (aka HD)

Some extra tips, if you apply many filters on one object it can become slow (at least it does on my poor little Mac Mini), so you can temporary disable them by clicking the View->Display mode->No Filters.  Also if you are interested in experimenting to display SVG directly in your application via a UIWebView you can take a look at the following article : 7 tips for using UIWebView.

Looking forward to see what cool vector graphic other iDev will create with Inkscape!

This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.

1 comment:

  1. Great post. Gonna give InkScape a try.