2011-10-07 51 views
0

我對於我正在製作的應用的iOS設備中的圖像存儲感到尷尬。iOS設備中的圖像存儲,適當的行爲?

我的要求是加載一個圖像到一個tableViewCell,讓我們說在一個UITableViewCell的默認圖像空間,因此不是一個背景圖像。

現在用戶可以通過PhotoDirectory添加圖像,也可以拍攝全新的圖像。

如果拍攝了新圖像,應該在哪裏存儲圖像?在默認的照片目錄?或在應用程序沙箱的文檔文件夾中?

因爲這些都是圖像文件,恐怕應用程序包內的商店圖像可能會讓它變得非常大,恐怕我不會過關大小限制。

性能明智,但是...什麼會更好的選擇?

+0

跨什麼限制?我能想到的唯一的應用程序大小限制就是從App Store提供您的應用程序。例如,一定尺寸的應用可以通過無線傳輸。 – Caleb

回答

-1

我有一個應用程序,也可以做一些你描述的事情。我的解決方案是創建一個叫做imageStore的單例。你可以找到關於一個單身人士的信息here

在這個imageStore中,我存儲了所有的「全尺寸」圖像;然而,就像你我擔心這些圖像的大小,所以不是直接使用它們,而是使用縮略圖。我做的是這個。對於我想在表格中表示的每個對象,我確保該對象具有一個與thumnail大小(64x64或任何您需要的大小)相關的UIImage。然後創建一個對象,我創建一個縮略圖,與對象一起存儲。我使用這個縮略圖,而不是更大的圖像,我可以通過它獲得方式,就像在一個表格單元格上一樣。

我現在不在我的Mac後面,但是如果你想我稍後可以發佈一些代碼來演示單身人士以及縮略圖的創建和使用。

下面是ImageStore

#import <Foundation/Foundation.h> 

@interface BPImageStore : NSObject { 
    NSMutableDictionary *dictionary; 
} 

+ (BPImageStore *)defaultImageStore; 

- (void)setImage:(UIImage *)i forKey:(NSString *)s; 
- (UIImage *)imageForKey:(NSString *)s; 
- (void)deleteImageForKey:(NSString *)s; 

@end 

這裏我的頭文件的ImageStore.m文件 - 我辛格爾頓

#import "BPImageStore.h" 

static BPImageStore *defaultImageStore = nil; 

@implementation BPImageStore 

+ (id)allocWithZone:(NSZone *)zone { 
    return [[self defaultImageStore] retain]; 
} 

+ (BPImageStore *)defaultImageStore { 
    if(!defaultImageStore) { 
     defaultImageStore = [[super allocWithZone:NULL] init]; 
    } 
    return defaultImageStore; 
} 

- (id)init 
{ 

    if(defaultImageStore) { 
     return defaultImageStore; 
    } 

    self = [super init]; 
    if (self) { 
     dictionary = [[NSMutableDictionary alloc] init]; 
     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
     [nc addObserver:self selector:@selector(clearCach:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 
    } 

    return self; 
} 

- (void) clearCache:(NSNotification *)note { 
    [dictionary removeAllObjects]; 
} 

- (oneway void) release { 
    // no op 
} 

- (id)retain { 
    return self; 
} 

- (NSUInteger)retainCount { 
    return NSUIntegerMax; 
} 

- (void)setImage:(UIImage *)i forKey:(NSString *)s { 
    [dictionary setObject:i forKey:s]; 

    // Create full path for image 
    NSString *imagePath = pathInDocumentDirectory(s); 

    // Turn image into JPEG data 
    NSData *d = UIImageJPEGRepresentation(i, 0.5); 

    // Write it to full path 
    [d writeToFile:imagePath atomically:YES]; 

} 

- (UIImage *)imageForKey:(NSString *)s { 
    // if possible, get it from the dictionary 
    UIImage *result = [dictionary objectForKey:s]; 
    if(!result) { 
     // Create UIImage object from file 
     result = [UIImage imageWithContentsOfFile:pathInDocumentDirectory(s)]; 
     if (result) 
      [dictionary setObject:result forKey:s]; 
    } 
    return result; 
} 

- (void)deleteImageForKey:(NSString *)s { 
    if(!s) { 
     return; 
    } 
    [dictionary removeObjectForKey:s]; 
    NSString *path = pathInDocumentDirectory(s); 
    [[NSFileManager defaultManager] removeItemAtPath:path error:NULL]; 
} 

@end 

這裏就是我用的是形象店。在我的對象「播放器」中,我有一個UIImage來存儲縮略圖,並且我有一個NSString來存放我創建的一個鍵。每個放入商店的原始圖像都有一個關鍵字。我用我的播放器存儲密鑰。如果我需要原始圖像,我可以通過唯一的鍵獲得。在這裏也值得注意的是,我甚至沒有將原始圖像以全尺寸存儲,我已經將它縮小了一些。所有在我的情況後,這是一個球員的照片,沒有人有太多看起來那麼好,以具有全分辨率圖片:)

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
    NSString *oldKey = [player imageKey]; 
    // did the player already have an image? 
    if(oldKey) { 
     // delete the old image 
     [[BPImageStore defaultImageStore] deleteImageForKey:oldKey]; 
    } 


    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; 

    // Create a CFUUID object it knows how to create unique identifier 
    CFUUIDRef newUniqueID = CFUUIDCreate(kCFAllocatorDefault); 

    // Create a string from unique identifier 
    CFStringRef newUniqueIDString = CFUUIDCreateString(kCFAllocatorDefault, newUniqueID); 

    // Use that unique ID to set our player imageKey 
    [player setImageKey:(NSString *)newUniqueIDString]; 

    // we used Create in the functions to make objects, we need to release them 
    CFRelease(newUniqueIDString); 
    CFRelease(newUniqueID); 

    //Scale the images down a bit 
    UIImage *smallImage = [self scaleImage:image toSize:CGSizeMake(160.0,240.0)]; 


    // Store image in the imageStore with this key 
    [[BPImageStore defaultImageStore] setImage:smallImage 
             forKey:[player imageKey]]; 

    // Put that image onto the screen in our image view 
    [playerView setImage:smallImage]; 

    [player setThumbnailDataFromImage:smallImage]; 
} 

這裏是回去得到從原始圖像的例子imageStore:

// Go get image 
NSString *imageKey = [player imageKey]; 
if (imageKey) { 
    // Get image for image key from image store 
    UIImage *imageToDisplay = [[BPImageStore defaultImageStore] imageForKey:imageKey]; 
    [playerView setImage:imageToDisplay]; 
} else { 
    [playerView setImage:nil]; 
} 

最後,這裏是我如何創建一個從原始圖像的縮略圖:

- (void)setThumbnailDataFromImage:(UIImage *)image { 
CGSize origImageSize = [image size]; 

CGRect newRect; 
newRect.origin = CGPointZero; 
newRect.size = [[self class] thumbnailSize]; // just give a size you want here instead 

// How do we scale the image 
float ratio = MAX(newRect.size.width/origImageSize.width, newRect.size.height/origImageSize.height); 

// Create a bitmap image context 
UIGraphicsBeginImageContext(newRect.size); 

// Round the corners 
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:newRect cornerRadius:5.0]; 

[path addClip]; 

// Into what rectangle shall I composite the image 
CGRect projectRect; 
projectRect.size.width = ratio * origImageSize.width; 
projectRect.size.height = ratio *origImageSize.height; 
projectRect.origin.x = (newRect.size.width - projectRect.size.width)/2.0; 
projectRect.origin.y = (newRect.size.height - projectRect.size.height)/2.0; 

// Draw the image on it 
[image drawInRect:projectRect]; 

// Get the image from the image context, retain it as our thumbnail 
UIImage *small = UIGraphicsGetImageFromCurrentImageContext(); 
[self setThumbnail:small]; 

// Get the image as a PNG data 
NSData *data = UIImagePNGRepresentation(small); 
[self setThumbnailData:data]; 

// Cleanup image context resources 
UIGraphicsEndImageContext(); 

}

+0

嘿謝謝你的回覆,我從概念上得到它!,如果你發佈,我真的可以使用一些代碼。它與我想要的非常相似! – user134611

+0

嘿,你的幫助對我的理解有很長的路要走。 – user134611

+0

我想再問一個問題,將縮略圖圖像存儲在文檔中並從那裏加載它是一個好主意嗎?考慮到可能會有很多圖像將被加載? – user134611

相關問題