Home > Graphics, Leopard, Six Days of Cocoa > Day Two: iChibi and ImageSoup

Day Two: iChibi and ImageSoup

April 20th, 2009

Six Days of Cocoa: Day Two

Day Two: code-name iChibi

My whole family is very much into all things japanese (including, of course, manga and anime). The other day, they found a little “sound-playing ghost” called Flele (I have no idea what the name means).

As far as I can tell, Flele is a small application that you drop one or more MP3s on, and it starts to “sing” when you click on the character’s hair. I have no idea how it actually works, since it requires Windows and the Japanese language pack. But my daughter and I quickly hashed out that what we could do would be a globally-floating iTunes controller, who would respond to click and animate when music was playing (we’ll figure out the “singing” part later).

iChibi

My daughter drew lots of PNGs this weekend (using Painter, of course), and we assembled them in sequences to make animations. The iChibi can blink, and lights turn on/off on its headphones whenever music is playing.

iChibi can be dragged anywhere on screen, and will float on top of all windows.

Clicking on its left ear starts playing in iTunes, on the right ear stops playing. The left headphone goes to the previous track, the right headphone to the next track.

Clicking on the zipper gives a Settings panel, where you can control the its size, opacity and which playlist the songs are coming from.

The higher the song rating, the happier it will look.

iTunes support is done through the excellent Eyetunes Framework.

iChibi works on MacOSX 10.5 and later.

If you are interested in following the development of iChibi, follow @ichibiapp on Twitter.


ImageSoup

Since iChibi uses lots of images for animations, and I didn’t want to keep multiple copies of the same image in memory (for example, if an image is re-used in multiple animation loops), I figured I should make a small class to hold all the images, loading them as necessary. I named this class ImageSoup, referring to the Newton’s filesystem of course…

ImageSoup is very simple, and does not need to be its own class (after all, it’s a dictionary). But it is nice to be able to abstract that implementation detail out of your code, as well as the image-loading code. What if your source image was an Acorn image or a Painter RIFF? You could hide the image-loading code in ImageSoup, and your calling code need not be aware of this.

To use ImageSoup, just create an ImageSoup* instance and always ask it to load your images (using the full path to the image):

#import "ImageSoup.h"

[...]

ImageSoup* allImages = [[ImageSoup alloc] init];

[...]

NSImage* myImage = [allImages getImageAtPath: @"Full/path/to/image"];

If the image exists and has been loaded previously, ImageSoup will return it right away. If the image does not exist, ImageSoup will load it and store it for future reference.

When you release your ImageSoup*, all its images will be released.

ImageSoup.h

//
//  ImageSoup.h
//  iChibi
//
//  Created by Philippe on 09-04-19.
//  Copyright 2009 Philippe Casgrain. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@interface ImageSoup : NSObject
{
  NSMutableDictionary* _images;
}

- (NSImage*) getImageAtPath: (NSString*) path;

@end

ImageSoup.m

//
//  ImageSoup.m
//  iChibi
//
//  Created by Philippe on 09-04-19.
//  Copyright 2009 Philippe Casgrain. All rights reserved.
//

#import "ImageSoup.h"

@implementation ImageSoup

- (id) init
{
  self = [super init];
  if (self != nil) 
  {
    _images = [[NSMutableDictionary dictionaryWithCapacity: 0] retain];
  }
  return self;
}

- (void) dealloc
{
  [_images removeAllObjects];
  [_images release];
  [super dealloc];
}


- (NSImage*) getImageAtPath: (NSString*) path
{
  NSImage* retrievedImage = [_images valueForKey: path];
  if (retrievedImage == nil)
  {
    NSImage* image = [[NSImage alloc] initWithContentsOfFile: path];
    if (image)
      [_images setObject: image forKey: path];
    [image release];
    retrievedImage = image;
  }
  return retrievedImage;
}

@end
Categories: Graphics, Leopard, Six Days of Cocoa Tags:
Comments are closed.