views:

494

answers:

1

Slower than what? slower than creating the same textures from an image loaded from the app bundle. How much slower ? 80 times slower on iPhone, similar ratio (but faster overall) on Mac.

My example below shows loading an image with imageNamed: ; creating textures from the first image ; saving image to a file in the app's Documents directory ; loading an image from that file ; creating textures from the second image.

Images are 640x640 png, 100 textures 64x64 are created in each case. Creation times are 0.51 s vs. 41.3 s.

Can anyone explain this huge difference, and point me to ways and means of speeding up the second case, to make it as fast as the first, if possible ?

Rudif

#import "Texture2D.h"

#define START_TIMER NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
#define END_TIMER NSTimeInterval stop = [NSDate timeIntervalSinceReferenceDate]; NSLog(@"Time = %f", stop-start); 


@interface UIImage (CS_Extensions)
-(UIImage *) imageAtRect:(CGRect)rect;
+(NSString *) documentsDirectory;
+(void) saveImage:(UIImage *)image toDocumentsFile:(NSString *)filename;
+(UIImage *) imageFromDocumentsFile:(NSString *)filename;
+(BOOL) documentsFileExists:(NSString *)filename;
+(void) createTexturesFromImage:(UIImage *)image640x640 texture:(Texture2D **)texture;

@end;

@implementation UIImage (MiscExt)

-(UIImage *)imageAtRect:(CGRect)rect {
 CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
 UIImage* subImage = [UIImage imageWithCGImage: imageRef];
 CGImageRelease(imageRef);
 return subImage;
}

+(NSString *) documentsDirectory {
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentsDirectory = [paths objectAtIndex:0];
 return documentsDirectory;
}

+(UIImage *) imageFromDocumentsFile:(NSString *)filename {
 // NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
 NSString *documentsDirectory = [self documentsDirectory];
 NSString *path = [NSString stringWithFormat:@"%@/%@", documentsDirectory, filename];
 NSLog(@"%s : path %@", __FUNCTION__, path);
 NSData *data = [[NSData alloc] initWithContentsOfFile:path];
 UIImage *image = [[UIImage alloc] initWithData:data];
 return image;
}

+(void) saveImage:(UIImage *)image toDocumentsFile:(NSString *)filename {
 if (image != nil) {  // save to local file
  //  NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
  NSString *documentsDirectory = [self documentsDirectory];
  NSString *path = [NSString stringWithFormat:@"%@/%@", documentsDirectory, filename];
  NSLog(@"%s : path %@", __FUNCTION__, path);
  //You can write an NSData to the fs w/ a method on NSData.
  //If you have a UIImage, you can do UIImageJPEGRepresentation() or UIImagePNGRepresentation to get data.
  NSData *data = UIImagePNGRepresentation(image);
  [data writeToFile:path atomically:YES];
  // Check if file exists
  NSFileManager *fileManager = [NSFileManager defaultManager];
  BOOL ok = [fileManager fileExistsAtPath:path];
  if (ok) {
   NSLog(@"%s : written file %@", __FUNCTION__, path);
  }
  else {
   NSLog(@"%s : failed to write file %@", __FUNCTION__, path);
  }
 }
}

+(BOOL) documentsFileExists:(NSString *)filename {
 NSString *documentsDirectory = [self documentsDirectory];
 NSString *path = [documentsDirectory stringByAppendingPathComponent:filename];
 NSLog(@"%s : path %@", __FUNCTION__, path);
 BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path];
 return exists;
}

+(void) createTexturesFromImage:(UIImage *)image640x640 texture:(Texture2D **)texture {
 NSLog(@"%s -> ", __FUNCTION__);
 START_TIMER;
 for (int x = 0; x < 9; ++x) {
  for (int y = 0; y < 9; ++y) {
   UIImage *ulCorner = [image640x640 imageAtRect:CGRectMake(x*64,y*64,64,64)];
   texture[y*10+x] = [[Texture2D alloc] initWithImage:ulCorner];
  }
 }
 END_TIMER;
 NSLog(@"%s <- ", __FUNCTION__);
}

@end


-(void) test {

 Texture2D *texture1[100];
 Texture2D *texture2[100];

 // compare texture creation from a bundled file vs Documents file
 {
  UIImage *imageBundled = [UIImage imageNamed:@"bivio-640x640.png"];
  [UIImage createTexturesFromImage:imageBundled texture:texture1];

  [UIImage saveImage:imageBundled toDocumentsFile:@"docfile.png"];
  BOOL ok = [UIImage documentsFileExists:@"docfile.png"];

  UIImage *imageFromFile = [UIImage imageFromDocumentsFile:@"docfile.png"];
  [UIImage createTexturesFromImage:imageFromFile texture:texture2];
 }
}
+1  A: 

When you built your project, XCode optimises PNGs that you put in resources.

This article explains it in details: http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html

nico