Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID

Image Caching Tutorial

chewbockachewbocka Posts: 49Tutorial Authors, Registered Users @
edited January 2012 in iPhone SDK Tutorials
If you're pulling in web data such as images that doesn't change but needs to be viewed multiple times, you'll want to cache it. Caching images dramatically improves the performance of scrolling tables and other views.

Note: this only works for JPG and PNG images. If you have suggestions or find bugs, let me know.

Utilities.h:
#import Foundation/Foundation.h

@interface Utilities : NSObject {

}

// Methods
- (void) cacheImage: (NSString *) ImageURLString;
- (UIImage *) getCachedImage: (NSString *) ImageURLString;
- (UIImage *) roundCorners: (UIImage*) img;

@end

Utilities.m
#import "Utilities.h"
#define TMP NSTemporaryDirectory()

@implementation Utilities

Function to actually cache the image - checks to see if one with the same name already exists
- (void) cacheImage: (NSString *) ImageURLString
{
    NSURL *ImageURL = [NSURL URLWithString: ImageURLString];
    
    // Generate a unique path to a resource representing the image you want
    NSString *filename = [[something unique, perhaps the image name]];
    NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];

    // Check for file existence
    if(![[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
    {
        // The file doesn't exist, we should get a copy of it

        // Fetch image
        NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
        UIImage *image = [[UIImage alloc] initWithData: data];
        
        // Do we want to round the corners?
        image = [self roundCorners: image];
        
        // Is it PNG or JPG/JPEG?
        // Running the image representation function writes the data from the image to a file
        if([ImageURLString rangeOfString: @".png" options: NSCaseInsensitiveSearch].location != NSNotFound)
        {
            [UIImagePNGRepresentation(image) writeToFile: uniquePath atomically: YES];
        }
        else if(
                [ImageURLString rangeOfString: @".jpg" options: NSCaseInsensitiveSearch].location != NSNotFound || 
                [ImageURLString rangeOfString: @".jpeg" options: NSCaseInsensitiveSearch].location != NSNotFound
                )
        {
            [UIImageJPEGRepresentation(image, 100) writeToFile: uniquePath atomically: YES];
        }
    }
}

Retrieve a cached file:
- (UIImage *) getCachedImage: (NSString *) ImageURLString
{
    NSString *filename = [[something unique, perhaps the image name]];
    NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];
    
    UIImage *image;
    
    // Check for a cached version
    if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
    {
        image = [UIImage imageWithContentsOfFile: uniquePath]; // this is the cached image
    }
    else
    {
        // get a new one
        [self cacheImage: ImageURLString];
        image = [UIImage imageWithContentsOfFile: uniquePath];
    }

    return image;
}

These two functions are just to add rounded corners to an image
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight)
{
    float fw, fh;
    if (ovalWidth == 0 || ovalHeight == 0)
    {
        CGContextAddRect(context, rect);
        return;
    }
    CGContextSaveGState(context);
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGContextScaleCTM (context, ovalWidth, ovalHeight);
    fw = CGRectGetWidth (rect) / ovalWidth;
    fh = CGRectGetHeight (rect) / ovalHeight;
    CGContextMoveToPoint(context, fw, fh/2);
    CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
    CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
    CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
    CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
    CGContextClosePath(context);
    CGContextRestoreGState(context);
}

- (UIImage *) roundCorners: (UIImage*) img
{
    int w = img.size.width;
    int h = img.size.height;
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
    
    CGContextBeginPath(context);
    CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
    addRoundedRectToPath(context, rect, 5, 5);
    CGContextClosePath(context);
    CGContextClip(context);
    
    CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
    
    CGImageRef imageMasked = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    [img release];
    
    return [UIImage imageWithCGImage:imageMasked];
}

@end
Post edited by chewbocka on
<a href="http://microblink.com" target="_blank">blog</a> | <a href="http://twitter.com/chewbocka" target="_blank">twitter</a>
«1

Replies

  • SteapsSteaps Posts: 469Tutorial Authors, Registered Users
    edited March 2009
    Just a suggestion, add in what each line does. This isn't much of a 'tutorial' as it's just a code snippet. :) Nice though, thanks.
    <div align="center"><b><a href="http://itunes.com/apps/quickevade" target="_blank">Evade - iPhone Game</a><br />
    <a href="http://itunes.com/apps/itasks" target="_blank">iTasks - Task Manager/Todo List</a><br />
    <a href="http://steaps.techaos.com/" targe
  • chewbockachewbocka Posts: 49Tutorial Authors, Registered Users @
    edited March 2009
    I guess I thought it was pretty self explanatory, but then again I wrote it :). I've got enough comments in there (I think) to explain each piece - explaining code line by line is a little over the top. I also broke each function into it's own section.

    I'm a bit of an Objective-C noob myself so I thought it would be nice to post helpful pieces of code that the community might benefit from.
    <a href="http://microblink.com" target="_blank">blog</a> | <a href="http://twitter.com/chewbocka" target="_blank">twitter</a>
  • SteapsSteaps Posts: 469Tutorial Authors, Registered Users
    edited March 2009
    chewbocka wrote: »
    I guess I thought it was pretty self explanatory, but then again I wrote it :). I've got enough comments in there (I think) to explain each piece - explaining code line by line is a little over the top. I also broke each function into it's own section.

    I'm a bit of an Objective-C noob myself so I thought it would be nice to post helpful pieces of code that the community might benefit from.

    Thats great! Thanks :).
    And yes, it is nice to post helpful pieces of code for the community.
    <div align="center"><b><a href="http://itunes.com/apps/quickevade" target="_blank">Evade - iPhone Game</a><br />
    <a href="http://itunes.com/apps/itasks" target="_blank">iTasks - Task Manager/Todo List</a><br />
    <a href="http://steaps.techaos.com/" targe
  • dvpwebdvpweb Posts: 1New Users
    edited May 2009
    Hey first off - thanks so much for your example- I'm very new to obj C and IPhone dev and found this utility to be very useful. Caching is such a common task.

    Some brief questions and suggestions:

    1> Where does the file go? What about cleanup, I'd hate to cache a few hundred images and then leave them in limbo?
    I did a NSLOG and see the file goes here...
    /var/folders/RJ/RJWwAcBZFtC36gaSUm0wKU+++TI/-Tmp-/ad.jpg

    I tried to use finder to actually find the file to delete it, so I can test it again.

    Suggestions or maybe post some additional help to extend the utilities class with two additional method (clearImage) to have a clear a single image (by filename) or the entire image cache (clearImageCache) ?

    BTW - I updated your original code to take a filename arg. It seemed like you'd want a handle on that - for doing things like the forementioned cleanup..

    Finally - here's an example of how to create and call your class:

    // Assumes you've included the class in the header.
    // ImageName is the url of an image (NSSTRING)
    //imgView is the image (UIImageView)

    Utilities *utils = [[Utilities alloc] init];
    UIImage *tempImg = [utils getCachedImage:ImageName];
    [imgView setImage:tempImg];
    // ...
    [Utilities release];

    Again fab example!
  • bj97301bj97301 Posts: 2New Users
    edited August 2009
    I am just wondering if there is a reason why you didn't just call the write function of the data from the url? If you do this then there will be support for all types of images. Below is some sample code demonstrating this.
    if(![[NSFileManager defaultManager] fileExistsAtPath: filePath])
    {
    	[[NSFileManager defaultManager] createDirectoryAtPath:TMP attributes:nil];
    	imageData=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:mapURL]];
    	[imageData writeToFile:filePath atomically:YES];
    	[imageData release];
    }
    
    tmpImg=[UIImage imageWithContentsOfFile: filePath];
    
    chewbocka wrote: »
    Note: this only works for JPG and PNG images. If you have suggestions or find bugs, let me know.
  • wolverinewolverine Posts: 181Registered Users
    edited December 2009
    Currently its taking me 0.8seconds for each image that i get from the server so if i cache 1000 images and then search for one to load, will it take more time to load than 0.8? I am currently running my app in simulator
  • wolverinewolverine Posts: 181Registered Users
    edited December 2009
    Steaps wrote: »
    Thats great! Thanks :).
    And yes, it is nice to post helpful pieces of code for the community.

    Hey steaps, how can i clear this cache everytime I close my app? I am doing this in simulator and its perfectly working for me. But I can see that even the next time when I come, its still there. So what should I do to clear the cache when I close?
  • J0kerJ0ker Posts: 59Registered Users
    edited December 2009
    wolverine wrote: »
    Hey steaps, how can i clear this cache everytime I close my app? I am doing this in simulator and its perfectly working for me. But I can see that even the next time when I come, its still there. So what should I do to clear the cache when I close?

    This is the reason why I used another approach. Instead of using TMP system directory, I create my own "tmp" directory in the Documents folder. I write there my cached file, and when I close the app in -applicationWillTerminate in the AppDelegate I delete that folder.
  • roydenroyden Posts: 33Registered Users
    edited June 2010
    Hi,

    Any idea this part:

    NSString *filename = [[something unique, perhaps the image name]]

    what code can i use in that box so that that the filename will be the original image name? thanks
  • ermikermik Posts: 8New Users
    edited August 2010
    Well this is all cool, but I don't think it's good in most cases. iPhone ships with NAND Memory built in which slowly dies-as-you-readwrite. I found good approach in "Advanced iPhone Projects" published Apress:
    With the iPhone’s NAND flash memory, writing is expensive both in terms of speed and in terms of hardware lifetime. It will eventually wear out with use. Apple recommends that you write to disk only when necessary. Since our application checks to see whether the data is stale, it is unlikely to download stock data more than once or twice per day, so you can reasonably store it to disk when it arrives. If your data were more often malleable, you might consider storing it only when the application closes or if you ran out of memory. In gogoDocs[Their App], we only download and write the updated feed if its last changed date is later than that of our cached information. This keeps the application from making unnecessary writes to the flash memory. Apple supplies a convenience method in your application’s delegate where you can save data before the app closes:
    -applicationWillTerminate:
    
  • zardonzardon Posts: 240Registered Users
    edited September 2010
    If you can cache images, can you also cache results from a sqlite database? I'm building an app with "football players" and there can be potentially thousands of records.
    UK-based Junior iOS developer looking for a job, or freelance projects.
  • dany_devdany_dev Posts: 4,696Tutorial Authors, Registered Users @ @ @ @ @
    edited September 2010
    zardon wrote: »
    If you can cache images, can you also cache results from a sqlite database? I'm building an app with "football players" and there can be potentially thousands of records.

    cache results from sqlite? :confused:

    sqlite is a database, there is no motive to cache a result from a database, generally a query need only few milliseconds.

    for example, also with 100,000 records, derive the data (40-50 entry?) from a ID of a player, would take approximately less than 1 second.
  • zardonzardon Posts: 240Registered Users
    edited September 2010
    dany88 wrote: »
    cache results from sqlite? :confused:

    sqlite is a database, there is no motive to cache a result from a database, generally a query need only few milliseconds.

    for example, also with 100,000 records, derive the data (40-50 entry?) from a ID of a player, would take approximately less than 1 second.

    I mean you don't put all the players inside an object, or an array if there is 1,000 records -- you would do something else; this is where I am stuck.
    UK-based Junior iOS developer looking for a job, or freelance projects.
  • JavaWizKidJavaWizKid Posts: 55Registered Users @
    edited November 2010
    I can't get the code to work properly, it might be something to do with
    NSString *filename = [[something unique, perhaps the image name]]
    

    I put
    NSString *filename = @"Test";
    

    Any ideas?
  • yuri1984yuri1984 Posts: 3New Users
    edited December 2010
    Hi,

    Dont know if anybody is still looking this subject , but i ll give it a try...

    I used chewbocka's tutorial...I added ns object named Utulities... i call it from cellForRowAtIndexPath: method, like this....

    int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
    NSString *theURL = [[stories objectAtIndex:storyIndex] objectForKey:@"image"];

    Utilities *utils = [[Utilities alloc] init];
    UIImage *tempImg = [utils getCachedImage:theURL];
    [cell.pic setImage:tempImg];

    Its always shows the same parsed image...All table cells shows same pic :S

    dont know what i'm doing wrong here :(

    could anobody help me?

    really thanks...
  • PeterMorgan2000PeterMorgan2000 Posts: 4New Users
    edited December 2010
    yuri1984 wrote: »
    Hi,

    Dont know if anybody is still looking this subject , but i ll give it a try...

    I used chewbocka's tutorial...I added ns object named Utulities... i call it from cellForRowAtIndexPath: method, like this....

    int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
    NSString *theURL = [[stories objectAtIndex:storyIndex] objectForKey:@"image"];

    Utilities *utils = [[Utilities alloc] init];
    UIImage *tempImg = [utils getCachedImage:theURL];
    [cell.pic setImage:tempImg];

    Its always shows the same parsed image...All table cells shows same pic :S

    dont know what i'm doing wrong here :(

    could anobody help me?

    really thanks...

    Hey Yuri,

    the reason it is always showing the same image is because the "storyIndex" isn't changing. It is always accessing the last object in the array.

    instead of:
    int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
    NSString *theURL = [[stories objectAtIndex:storyIndex]
    objectForKey:@"image"];

    try
    NSString *theURL = [[stories objectAtIndex:indexPath.row] objectForKey:@"image"];
  • yuri1984yuri1984 Posts: 3New Users
    edited December 2010
    Hi Peter,

    Thank you for your reply...i tried what you said..i did'nt get error but its still same..:(

    i put NS logs to utulities.m methots and here whats going on...

    - (UIImage *) getCachedImage: (NSString *) ImageURLString
    {
    NSString *filename = @"haberler3";
    NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];

    UIImage *image;

    // Check for a cached version
    if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
    {
    NSLog(@"Cashe");
    image = [UIImage imageWithContentsOfFile: uniquePath]; // this is the cached image
    }
    else
    {
    // get a new one

    [self cacheImage: ImageURLString];

    NSLog(@"casheImage called");
    image = [UIImage imageWithContentsOfFile: uniquePath];
    }


    return image;
    }


    and my console is like this,

    2010-12-03 23:50:48.997 KP2[2376:207] ImageUrl: http://news.bbcimg.co.uk/media/images/50274000/jpg/_50274482_alcott66a.jpg
    2010-12-03 23:50:48.997 KP2[2376:207] adding story: Alcott breaks leg in Lake Louise
    2010-12-03 23:50:48.998 KP2[2376:207] add yaptı: http://news.bbcimg.co.uk/media/images/50274000/jpg/_50274482_alcott66a.jpg
    2010-12-03 23:50:48.998 KP2[2376:207] date: Fri, 03 Dec 2010 06:57:29 GMT
    2010-12-03 23:50:48.999 KP2[2376:207] ImageUrl: http://news.bbcimg.co.uk/media/images/50281000/jpg/_50281502_snow-leaopard.jpg
    2010-12-03 23:50:48.999 KP2[2376:207] adding story: 'Snow Leopard' launches Ghana ski centre bid
    2010-12-03 23:50:49.000 KP2[2376:207] add yaptı: http://news.bbcimg.co.uk/media/images/50281000/jpg/_50281502_snow-leaopard.jpg
    2010-12-03 23:50:49.000 KP2[2376:207] date: Fri, 03 Dec 2010 13:15:28 GMT
    2010-12-03 23:50:49.027 KP2[2376:207] Cashe
    2010-12-03 23:50:49.031 KP2[2376:207] Cashe
    2010-12-03 23:50:49.033 KP2[2376:207] Cashe
    2010-12-03 23:50:49.035 KP2[2376:207] Cashe
    2010-12-03 23:50:49.037 KP2[2376:207] Cashe
    2010-12-03 23:50:53.839 KP2[2376:207] Cashe
    2010-12-03 23:50:54.005 KP2[2376:207] Cashe
    2010-12-03 23:50:54.255 KP2[2376:207] Cashe
    2010-12-03 23:50:54.740 KP2[2376:207] Cashe
    2010-12-03 23:50:54.972 KP2[2376:207] Cashe
    2010-12-03 23:50:55.022 KP2[2376:207] Cashe
    2010-12-03 23:50:55.072 KP2[2376:207] Cashe
    2010-12-03 23:50:55.122 KP2[2376:207] Cashe
    2010-12-03 23:50:55.189 KP2[2376:207] Cashe
    2010-12-03 23:50:55.256 KP2[2376:207] Cashe
    2010-12-03 23:50:55.822 KP2[2376:207] Cashe

    dont know why its always calling cash... it looks like method doesnt passes to 'else' part :(

    thank you for your help...
  • PeterMorgan2000PeterMorgan2000 Posts: 4New Users
    edited December 2010
    yuri1984 wrote: »
    Hi Peter,

    Thank you for your reply...i tried what you said..i did'nt get error but its still same..:( ....

    The "Filename" string you are using to get the "UniquePath" must be unique itself. It must correspond to the filename of image you have cached. As you have it now all of the images are being cached under the filename "haberler3", so when you are retrieving the images it is always pointing to the same image. Give each image you want to cache a unique filename.

    try this:
    - (void) cacheImage: (NSString *) ImageURLString imageName:(NSString*)imageName
    {
        NSURL *ImageURL = [NSURL URLWithString: ImageURLString];
        
        // Generate a unique path to a resource representing the image you want
        NSString *filename = imageName;
        NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];
    	
        // Check for file existence
        if(![[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
        {
            // The file doesn't exist, we should get a copy of it
    		
            // Fetch image
            NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
            UIImage *image = [[UIImage alloc] initWithData: data];
            
            // Do we want to round the corners?
            image = [self roundCorners: image];
            
            // Is it PNG or JPG/JPEG?
            // Running the image representation function writes the data from the image to a file
            if([ImageURLString rangeOfString: @".png" options: NSCaseInsensitiveSearch].location != NSNotFound)
            {
                [UIImagePNGRepresentation(image) writeToFile: uniquePath atomically: YES];
            }
            else if(
                    [ImageURLString rangeOfString: @".jpg" options: NSCaseInsensitiveSearch].location != NSNotFound || 
                    [ImageURLString rangeOfString: @".jpeg" options: NSCaseInsensitiveSearch].location != NSNotFound
                    )
            {
                [UIImageJPEGRepresentation(image, 100) writeToFile: uniquePath atomically: YES];
            }
        }
    }
    
    - (UIImage *) getCachedImage: (NSString *) ImageURLString imageName:(NSString*)imageName
    {
        NSString *filename = imageName;
        NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];
        
        UIImage *image;
        
        // Check for a cached version
        if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
        {
            image = [UIImage imageWithContentsOfFile: uniquePath]; // this is the cached image
        }
        else
        {
            // get a new one
            [self cacheImage: ImageURLString imageName:imageName];
            image = [UIImage imageWithContentsOfFile: uniquePath];
        }
    
        return image;
    }
    

    and insert a different "imageName" for each image you want to cache.

    I hope this helps.

    Peter
  • yuri1984yuri1984 Posts: 3New Users
    edited December 2010
    Hi Peter,

    i finnally managed it to work...but it didn't work the way i though... Scrolling is laggy at first scroll...('till images downloaded) . i want images to be downloaded at start-up. Anyway, you were so helpfull... Thank you..
  • intomointomo Posts: 62Registered Users
    edited December 2010
  • iSDKiSDK Posts: 1,353Tutorial Authors, Registered Users
    edited January 2011
    hey, I have made a class file I plan on uploading to github,would you mind if I use your methods in the class file?

    Thanks
    chewbocka wrote: »
    If you're pulling in web data such as images that doesn't change but needs to be viewed multiple times, you'll want to cache it. Caching images dramatically improves the performance of scrolling tables and other views.

    Note: this only works for JPG and PNG images. If you have suggestions or find bugs, let me know.

    Utilities.h:
    #import Foundation/Foundation.h
    
    @interface Utilities : NSObject {
    
    }
    
    // Methods
    - (void) cacheImage: (NSString *) ImageURLString;
    - (UIImage *) getCachedImage: (NSString *) ImageURLString;
    - (UIImage *) roundCorners: (UIImage*) img;
    
    @end
    

    Utilities.m
    #import "Utilities.h"
    #define TMP NSTemporaryDirectory()
    
    @implementation Utilities
    

    Function to actually cache the image - checks to see if one with the same name already exists
    - (void) cacheImage: (NSString *) ImageURLString
    {
        NSURL *ImageURL = [NSURL URLWithString: ImageURLString];
        
        // Generate a unique path to a resource representing the image you want
        NSString *filename = [[something unique, perhaps the image name]];
        NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];
    
        // Check for file existence
        if(![[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
        {
            // The file doesn't exist, we should get a copy of it
    
            // Fetch image
            NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
            UIImage *image = [[UIImage alloc] initWithData: data];
            
            // Do we want to round the corners?
            image = [self roundCorners: image];
            
            // Is it PNG or JPG/JPEG?
            // Running the image representation function writes the data from the image to a file
            if([ImageURLString rangeOfString: @".png" options: NSCaseInsensitiveSearch].location != NSNotFound)
            {
                [UIImagePNGRepresentation(image) writeToFile: uniquePath atomically: YES];
            }
            else if(
                    [ImageURLString rangeOfString: @".jpg" options: NSCaseInsensitiveSearch].location != NSNotFound || 
                    [ImageURLString rangeOfString: @".jpeg" options: NSCaseInsensitiveSearch].location != NSNotFound
                    )
            {
                [UIImageJPEGRepresentation(image, 100) writeToFile: uniquePath atomically: YES];
            }
        }
    }
    

    Retrieve a cached file:
    - (UIImage *) getCachedImage: (NSString *) ImageURLString
    {
        NSString *filename = [[something unique, perhaps the image name]];
        NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];
        
        UIImage *image;
        
        // Check for a cached version
        if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
        {
            image = [UIImage imageWithContentsOfFile: uniquePath]; // this is the cached image
        }
        else
        {
            // get a new one
            [self cacheImage: ImageURLString];
            image = [UIImage imageWithContentsOfFile: uniquePath];
        }
    
        return image;
    }
    

    These two functions are just to add rounded corners to an image
    static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight)
    {
        float fw, fh;
        if (ovalWidth == 0 || ovalHeight == 0)
        {
            CGContextAddRect(context, rect);
            return;
        }
        CGContextSaveGState(context);
        CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
        CGContextScaleCTM (context, ovalWidth, ovalHeight);
        fw = CGRectGetWidth (rect) / ovalWidth;
        fh = CGRectGetHeight (rect) / ovalHeight;
        CGContextMoveToPoint(context, fw, fh/2);
        CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
        CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
        CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
        CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
        CGContextClosePath(context);
        CGContextRestoreGState(context);
    }
    
    - (UIImage *) roundCorners: (UIImage*) img
    {
        int w = img.size.width;
        int h = img.size.height;
        
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
        
        CGContextBeginPath(context);
        CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
        addRoundedRectToPath(context, rect, 5, 5);
        CGContextClosePath(context);
        CGContextClip(context);
        
        CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
        
        CGImageRef imageMasked = CGBitmapContextCreateImage(context);
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
        [img release];
        
        return [UIImage imageWithCGImage:imageMasked];
    }
    
    @end
    
  • mesohornymesohorny Posts: 69Banned Members
    edited May 2011
    hi, nice snippet , don't forget to always release what you alloc/init

    [data release];
    [image release];

    in - (UIImage *)getImage: (NSString *) ImageURLString

    cheers
  • franzwarningfranzwarning Posts: 194Registered Users
    edited May 2011
    so how do you clear the cache then? and what is the max amount of data the cache can hold?

    -Cheers,
    George
  • blackbook1991blackbook1991 Posts: 20Tutorial Authors, Registered Users
    edited August 2011
    Hi!

    Do you guys have a simple working code/project I can download that uses this tutorial? :)
    <a href="http://haifa.baluyos.net" target="_blank">Enjoy All The Way!</a> <img src="http://www.iphonedevsdk.com/forum/images/smilies/biggrin.gif" border="0" alt="" title="Big Grin" class="inlineimg" />
  • cutecutecutecute Posts: 12Registered Users
    edited October 2011
    Thanks for your guide:)
    <a href="http://apps24h.com/" target="_blank">Iphone Game News and Reviews</a>
«1
Sign In or Register to comment.