Using Images in iOS
Jeff Kelley | @SlaunchaMan
MobiDevDay, May 4, 2013
Saturday, May 4, 13
Slide 2
Slide 2 text
Who Am I?
Saturday, May 4, 13
Slide 3
Slide 3 text
Using Images in iOS
Saturday, May 4, 13
Slide 4
Slide 4 text
Using Images in iOS
Saturday, May 4, 13
Slide 5
Slide 5 text
Why A Talk About Images?
Saturday, May 4, 13
Slide 6
Slide 6 text
iDevice Displays
Saturday, May 4, 13
Slide 7
Slide 7 text
Image Pitfalls
• One uncompressed Retina iPad image file:
~12 MB
• App Store download limit for non-WiFi
connections: 50 MB
• One uncompressed background image for
all resolutions: ~18 MB
Saturday, May 4, 13
Special Images in the
Bundle
• iTunes Artwork
• Include as ‘iTunesArtwork’ (no extension)
for ad-hoc builds
• now must be 1024x1024
• Warn your designer!
• Consider using vector graphics
Saturday, May 4, 13
Slide 10
Slide 10 text
Special Images in the
Bundle
• Default Images
• Display while your app is launching
• One for each resolution/rotation
• Separate image for iPhone 5
• The presence of this image indicates
whether your app has iPhone 5
support
Saturday, May 4, 13
Slide 11
Slide 11 text
How can we balance good UIs with image
sizes?
Saturday, May 4, 13
Slide 12
Slide 12 text
Retina Graphics
• Everything on an iOS display is measured in
points, not pixels
• To get the pixel dimensions of an image,
multiply scale by size
• Images created with +imageNamed:
automatically seek out image files with the
“@2x” suffix before the extension
• “image.png” and “[email protected]”
Saturday, May 4, 13
Slide 13
Slide 13 text
Retina Graphics
• Tell your designers: design for non-Retina,
create for Retina
• Yes, this is hard.
• Retina graphics must be exactly twice the
scale—no odd dimensions.
• Even with drop shadows!
Saturday, May 4, 13
Slide 14
Slide 14 text
Stretchable Images
• Once you have an image, you can create a
resizable version that can resize to any
arbitrary size
•- (UIImage *)resizableImageWithCapInsets:
(UIEdgeInsets)capInsets;
• The inner portion is tiled or stretched
Saturday, May 4, 13
Slide 15
Slide 15 text
Stretchable Images
Top
Bottom
Left Right
Saturday, May 4, 13
Slide 16
Slide 16 text
Demo
Saturday, May 4, 13
Slide 17
Slide 17 text
Animated Images
• Load individual frames of an animation as
separate images and cycle through them
• Can initialize with an array of images or
with a prefix
• Up to 1,024 frames
Saturday, May 4, 13
Slide 18
Slide 18 text
Animated Images
• Creating from a prefix:
+ (UIImage *)animatedImageNamed:(NSString *)name
duration:(NSTimeInterval)duration;
• Creating from an array:
+ (UIImage *)animatedImageWithImages:(NSArray
*)images duration:(NSTimeInterval)duration;
Saturday, May 4, 13
Slide 19
Slide 19 text
Demo
Saturday, May 4, 13
Slide 20
Slide 20 text
Animated Images
• If you’re really crazy:
•+ (UIImage *)animatedResizableImageNamed:(NSString
*)name capInsets:(UIEdgeInsets)capInsets duration:
(NSTimeInterval)duration;
Saturday, May 4, 13
Slide 21
Slide 21 text
Image Patterns
• Sometimes you want to make a tiny image
repeat, such as in a background
• Create a UIColor object with the image as
a pattern:
UIColor *myPatternColor = [UIColor
colorWithPatternImage:myImage];
• Great way to save space
Saturday, May 4, 13
Slide 22
Slide 22 text
Demo
Saturday, May 4, 13
Slide 23
Slide 23 text
“We’ll Do It Live!”:
Rendering with
CoreGraphics
Saturday, May 4, 13
Slide 24
Slide 24 text
CoreGraphics
• AKA QuartzCore
•
• Allows you to draw graphics yourself as
opposed to including images
Saturday, May 4, 13
Slide 25
Slide 25 text
Custom View Rendering
• The easiest path to custom drawing
• Override -drawRect:
Saturday, May 4, 13
Slide 26
Slide 26 text
Graphics Contexts
• Graphics contexts, represented by the
CGContext opaque type, are the thing you
draw into
• In -drawRect:, you can get the current
context with
UIGraphicsGetCurrentContext()
Saturday, May 4, 13
Slide 27
Slide 27 text
Demo
Saturday, May 4, 13
Slide 28
Slide 28 text
Custom Drawing
• A view doesn’t always redraw itself
• Call -setNeedsDisplay to mark it as dirty
• When marked as dirty, will re-draw in the
event loop
Saturday, May 4, 13
Slide 29
Slide 29 text
Custom Drawing
• Can be a performance problem
• Lots of duplicate rendering effort
Saturday, May 4, 13
Slide 30
Slide 30 text
Problem: Interpolation
• Images resized in UIImageViews have no
control over interpolation quality
• Bad solution: multiple images in the bundle,
resized to the necessary sizes
• How can we resize an image with good
quality?
Saturday, May 4, 13
Slide 31
Slide 31 text
Interpolating with
CoreGraphics
• Create a new bitmap graphics context
• Set its interpolation quality to high
• Draw the original image into the context
• Get a new image
Saturday, May 4, 13
Slide 32
Slide 32 text
Demo
Saturday, May 4, 13
Slide 33
Slide 33 text
Image Data
• CoreGraphics is fun and all, but sometimes
you need to access pixel data
• What is pixel data? How is it formatted
• iOS uses (mostly) RGBA8888 format
• What the heck does that mean?
Saturday, May 4, 13
Slide 34
Slide 34 text
Color Spaces
• CGColorSpace opaque type
• Two main color spaces to worry about:
• CGColorSpaceCreateDeviceGray()
• CGColorSpaceCreateDeviceRGB()
• Defines the number of components
Saturday, May 4, 13
Getting Pixel Data
• Create a buffer of pixel data to draw into
• We’ll use uint8_t for unsigned 8-bit
integers
• Create a bitmap image context
• Draw the image into the context
• Voilà!
Saturday, May 4, 13
Slide 37
Slide 37 text
Getting Pixel Data
• Why didn’t we just ask the image for its
data?
• Drawing it into our own context give us a
mutable version of it
• We know the color space we’re using
Saturday, May 4, 13
Slide 38
Slide 38 text
Demo
Saturday, May 4, 13
Slide 39
Slide 39 text
Generating Pixel Data
• Remember before when we made a bitmap
graphics context with data?
• Turns out you can pre-fill that data with
your own pixels
Saturday, May 4, 13
Slide 40
Slide 40 text
Demo
Saturday, May 4, 13
Slide 41
Slide 41 text
Edge Cases
Saturday, May 4, 13
Slide 42
Slide 42 text
Huge Images
• What do you do if you get an image URL
and the image is 2GB?
• How do you fit a super hi-res image on an
iPhone 3GS screen? Retina iPad?
Saturday, May 4, 13
Slide 43
Slide 43 text
Huge Images
• Instead of keeping the downloaded bits in
memory, write them directly to the disk
• Instead of loading the entire image to resize
it, use ImageIO to generate a thumbnail
efficiently
Saturday, May 4, 13
Slide 44
Slide 44 text
ImageIO
Saturday, May 4, 13
Slide 45
Slide 45 text
Demo
Saturday, May 4, 13
Slide 46
Slide 46 text
Huge Images
• That works well for a static image, but what
if it’s a .gif?
• Most apps punt and put it in a UIWebView.
Then crash when the image is huge.
• Theoretically we should be able to run a
2GB .gif on an iPhone 3GS
• Working on it!
Saturday, May 4, 13
Slide 47
Slide 47 text
Huge Images
• What if you want to zoom into an image?
• CATiledLayer to provide individual tiles
• Have the image already? Cut it up
beforehand.
• Downloading the image? Split it up
dynamically using libjpeg with
PhotoScrollerNetwork
Saturday, May 4, 13