Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Tutorials

Reply
 
LinkBack Thread Tools Display Modes
Old 03-13-2009, 12:08 PM   #1 (permalink)
Tutorial Author
 
Join Date: Feb 2009
Posts: 49
Default Image Caching Tutorial

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:
Code:
#import Foundation/Foundation.h

@interface Utilities : NSObject {

}

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

@end
Utilities.m
Code:
#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
Code:
- (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:
Code:
- (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
Code:
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
__________________
blog | twitter

Last edited by chewbocka; 03-13-2009 at 03:55 PM. Reason: added more explanation
chewbocka is offline   Reply With Quote
Old 03-13-2009, 03:47 PM   #2 (permalink)
Tutorial Author
 
Steaps's Avatar
 
Join Date: Oct 2008
Location: Ontario, Canada
Posts: 466
Default

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.
Steaps is offline   Reply With Quote
Old 03-13-2009, 03:59 PM   #3 (permalink)
Tutorial Author
 
Join Date: Feb 2009
Posts: 49
Default

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.
__________________
blog | twitter
chewbocka is offline   Reply With Quote
Old 03-13-2009, 06:27 PM   #4 (permalink)
Tutorial Author
 
Steaps's Avatar
 
Join Date: Oct 2008
Location: Ontario, Canada
Posts: 466
Default

Quote:
Originally Posted by chewbocka View Post
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.
Steaps is offline   Reply With Quote
Old 05-13-2009, 11:12 AM   #5 (permalink)
New Member
 
Join Date: May 2009
Posts: 1
Default Brilliant Example!

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!

Last edited by dvpweb; 05-13-2009 at 11:14 AM.
dvpweb is offline   Reply With Quote
Old 08-17-2009, 06:39 PM   #6 (permalink)
Registered Member
 
Join Date: Aug 2009
Posts: 2
Default JPG and PNG support only

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.

Code:
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];
Quote:
Originally Posted by chewbocka View Post
Note: this only works for JPG and PNG images. If you have suggestions or find bugs, let me know.
bj97301 is offline   Reply With Quote
Old 12-08-2009, 07:04 AM   #7 (permalink)
Registered Member
 
Join Date: Jun 2009
Posts: 181
Smile

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
wolverine is offline   Reply With Quote
Old 12-09-2009, 02:34 AM   #8 (permalink)
Registered Member
 
Join Date: Jun 2009
Posts: 181
Smile

Quote:
Originally Posted by Steaps View Post
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?
wolverine is offline   Reply With Quote
Old 12-10-2009, 05:58 PM   #9 (permalink)
Registered Member
 
Join Date: Jul 2009
Posts: 59
Thumbs up

Quote:
Originally Posted by wolverine View Post
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.
J0ker is offline   Reply With Quote
Old 06-15-2010, 03:56 AM   #10 (permalink)
Registered Member
 
Join Date: May 2010
Posts: 33
Default

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
royden is offline   Reply With Quote
Old 08-18-2010, 01:08 PM   #11 (permalink)
Registered Member
 
Join Date: Aug 2010
Posts: 8
Default

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:
Quote:
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:
Code:
-applicationWillTerminate:
ermik is offline   Reply With Quote
Old 09-12-2010, 03:28 PM   #12 (permalink)
Registered Member
 
Join Date: Jul 2010
Location: UK, North East
Posts: 214
Default

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.
zardon is offline   Reply With Quote
Old 09-13-2010, 05:16 AM   #13 (permalink)
Nuisance Developer
 
Join Date: Jul 2009
Location: Italy
Posts: 4,691
Default

Quote:
Originally Posted by zardon View Post
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?

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.
__________________

Last edited by dany_dev; 09-13-2010 at 05:19 AM.
dany_dev is offline   Reply With Quote
Old 09-13-2010, 06:15 AM   #14 (permalink)
Registered Member
 
Join Date: Jul 2010
Location: UK, North East
Posts: 214
Default

Quote:
Originally Posted by dany88 View Post
cache results from sqlite?

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.
zardon is offline   Reply With Quote
Old 11-21-2010, 05:32 PM   #15 (permalink)
Registered Member
 
Join Date: Aug 2009
Posts: 48
Default

I can't get the code to work properly, it might be something to do with

Code:
NSString *filename = [[something unique, perhaps the image name]]
I put
Code:
NSString *filename = @"Test";
Any ideas?
__________________
Discover new apps through art! Sound weird? Check it out! BigAppAd!
Follow me on Twitter!
JavaWizKid is offline   Reply With Quote
Old 12-01-2010, 02:51 PM   #16 (permalink)
Registered Member
 
Join Date: Dec 2010
Posts: 3
Default

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...
yuri1984 is offline   Reply With Quote
Old 12-03-2010, 12:44 PM   #17 (permalink)
Registered Member
 
Join Date: Dec 2010
Posts: 4
Default

Quote:
Originally Posted by yuri1984 View Post
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"];
PeterMorgan2000 is offline   Reply With Quote
Old 12-03-2010, 04:56 PM   #18 (permalink)
Registered Member
 
Join Date: Dec 2010
Posts: 3
Default

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/image..._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/image..._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/image...w-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/image...w-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...
yuri1984 is offline   Reply With Quote
Old 12-05-2010, 08:55 AM   #19 (permalink)
Registered Member
 
Join Date: Dec 2010
Posts: 4
Default

Quote:
Originally Posted by yuri1984 View Post
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:
Code:
- (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
PeterMorgan2000 is offline   Reply With Quote
Old 12-06-2010, 01:38 PM   #20 (permalink)
Registered Member
 
Join Date: Dec 2010
Posts: 3
Default

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..
yuri1984 is offline   Reply With Quote
Old 12-14-2010, 11:02 AM   #21 (permalink)
Registered Member
 
Join Date: Jul 2009
Posts: 62
Default

Check out ASIHTTPRequest Documentation - All-Seeing Interactive

This lib makes downloading images a lot easier.
intomo is offline   Reply With Quote
Old 01-13-2011, 02:11 PM   #22 (permalink)
Indie Developer
 
iSDK's Avatar
 
Join Date: Jul 2010
Posts: 1,333
Send a message via AIM to iSDK
Default

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

Quote:
Originally Posted by chewbocka View Post
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:
Code:
#import Foundation/Foundation.h

@interface Utilities : NSObject {

}

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

@end
Utilities.m
Code:
#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
Code:
- (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:
Code:
- (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
Code:
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
iSDK is offline   Reply With Quote
Old 05-11-2011, 12:17 PM   #23 (permalink)
Banned
 
Join Date: Jan 2009
Posts: 69
Default leak

hi, nice snippet , don't forget to always release what you alloc/init

[data release];
[image release];

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

cheers
mesohorny is offline   Reply With Quote
Old 05-11-2011, 02:31 PM   #24 (permalink)
New to the SDK
 
franzwarning's Avatar
 
Join Date: Jul 2010
Location: Newport Beach, CA
Age: 18
Posts: 152
Send a message via AIM to franzwarning Send a message via Skype™ to franzwarning
Default

so how do you clear the cache then? and what is the max amount of data the cache can hold?

-Cheers,
George
franzwarning is offline   Reply With Quote
Old 08-22-2011, 02:15 AM   #25 (permalink)
Registered Member
 
blackbook1991's Avatar
 
Join Date: Aug 2011
Posts: 20
Send a message via Yahoo to blackbook1991
Default

Hi!

Do you guys have a simple working code/project I can download that uses this tutorial?
__________________
Enjoy All The Way!
blackbook1991 is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 245
18 members and 227 guests
ADY, Alsahir, beleg_1998, Dani77, e2applets, iDifferent, iph_s, JamesCahall, JasonR, mer10, Monstertaco, prchn4christ, Promo Dispenser, Robiwan, Rudy, smithdale87, spiderguy84, timle8n1
Most users ever online was 1,187, 10-11-2011 at 08:09 AM.
» Stats
Members: 158,880
Threads: 89,228
Posts: 380,756
Top Poster: BrianSlick (7,129)
Welcome to our newest member, @sandris
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 01:17 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0