當遊戲第一次運行時,我需要生成並保存320個圖像作爲PNG。這些圖像將被加載而不是再次生成。下面是該過程:首次啓動時生成並存儲許多圖像iOS
- 負載圖像模板(黑色和白色的阿爾法)
- 覆蓋非與指定的顏色的透明像素
- 放在上面以0.3的不透明度它合併到一個最終圖像模板
- 返回回來的UIImage
- 店的UIImage,在緩存目錄轉換爲NSData的爲PNG
這是使用UIGraph完成icsBeginImageContextWithOptions。此過程需要在後臺線程上的10種顏色中的32個圖像模板完成。目的是在遊戲中將這些圖像用作頭像/頭像,並在適當的時候在某些屏幕上縮小。但它們不能每次都生成,因爲這會導致太多滯後。
圖像是400x400每個。它們的結果是每個存儲時大約20/25 kB。當我嘗試使用我目前的生成和存儲方式時,我收到一條內存警告,並且看到(使用儀器)CGImage和UIImage對象的數量不斷增加。這似乎是他們被保留,但我沒有任何參考。
這裏是我的其他問題更密切的細節我正在使用的代碼:UIGraphicsBeginImageContext created image
什麼是創建並存儲到二級存儲這麼多圖像最好方式是什麼?提前致謝。
編輯:
這裏是整個代碼我目前使用它來創建並保存圖像:
//==========================================================
// Definitions and Macros
//==========================================================
//HEX color macro
#define UIColorFromRGB(rgbValue) [UIColor \
colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
//Colours
#define RED_COLOUR UIColorFromRGB(0xF65D58)
#define ORANGE_COLOUR UIColorFromRGB(0xFF8D16)
#define YELLOW_COLOUR UIColorFromRGB(0xFFD100)
#define LIGHT_GREEN_COLOUR UIColorFromRGB(0x82DE13)
#define DARK_GREEN_COLOUR UIColorFromRGB(0x67B74F)
#define TURQUOISE_COLOUR UIColorFromRGB(0x32ADA6)
#define LIGHT_BLUE_COLOUR UIColorFromRGB(0x11C9FF)
#define DARK_BLUE_COLOUR UIColorFromRGB(0x2E97F5)
#define PURPLE_COLOUR UIColorFromRGB(0x8F73FD)
#define PINK_COLOUR UIColorFromRGB(0xF35991)
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//Generate the graphics
[self generateAndSaveGraphics];
}
//==========================================================
// Generating and Saving Graphics
//==========================================================
-(void)generateAndSaveGraphics {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self createAvatarImages];
//Here create all other images that need to be saved to Cache directory
dispatch_async(dispatch_get_main_queue(), ^{ //Finished
NSLog(@"DONE"); //always runs out of memory before getting here
});
});
}
-(void)createAvatarImages {
//Create avatar images
NSArray *colours = [NSArray arrayWithObjects:RED_COLOUR, ORANGE_COLOUR, YELLOW_COLOUR, LIGHT_GREEN_COLOUR, DARK_GREEN_COLOUR, TURQUOISE_COLOUR, LIGHT_BLUE_COLOUR, DARK_BLUE_COLOUR, PURPLE_COLOUR, PINK_COLOUR, nil];
NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
for(int i = 0; i < 32; i++) { //Avatar image templates are named m1 - m16 and f1 - f16
NSString *avatarImageName;
if(i < 16) { //female avatars
avatarImageName = [NSString stringWithFormat:@"f%i", i+1];
}
else { //male avatars
avatarImageName = [NSString stringWithFormat:@"m%i", i-15];
}
for(int j = 0; j < colours.count; j++) { //make avatar image for each colour
@autoreleasepool { //only helps very slightly
UIColor *colour = [colours objectAtIndex:j];
UIImage *avatarImage = [self tintedImageFromImage:[UIImage imageNamed:avatarImageName] colour:colour intensity:0.3];
NSString *fileName = [NSString stringWithFormat:@"%@_%i.png", avatarImageName, j];
NSString *filePath = [cacheDir stringByAppendingPathComponent:fileName];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(avatarImage)];
[imageData writeToFile:filePath atomically:YES];
NSLog(@"AVATAR IMAGE CREATED");
}
}
}
}
//==========================================================
// Universal Image Tinting Code
//==========================================================
//Creates a tinted image based on the source greyscale image and tinting intensity
-(UIImage *)tintedImageFromImage:(UIImage *)sourceImage colour:(UIColor *)color intensity:(float)intensity {
if (UIGraphicsBeginImageContextWithOptions != NULL) {
UIGraphicsBeginImageContextWithOptions(sourceImage.size, NO, 0.0);
} else {
UIGraphicsBeginImageContext(sourceImage.size);
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rect = CGRectMake(0, 0, sourceImage.size.width, sourceImage.size.height);
// draw alpha-mask
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, sourceImage.CGImage);
// draw tint color, preserving alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
[color setFill];
CGContextFillRect(context, rect);
//Set the original greyscale template as the overlay of the new image
sourceImage = [self verticallyFlipImage:sourceImage];
[sourceImage drawInRect:CGRectMake(0,0, sourceImage.size.width,sourceImage.size.height) blendMode:kCGBlendModeMultiply alpha:intensity];
UIImage *colouredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
colouredImage = [self verticallyFlipImage:colouredImage];
return colouredImage;
}
//Vertically flips an image
-(UIImage *)verticallyFlipImage:(UIImage *)originalImage {
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:originalImage];
UIGraphicsBeginImageContext(tempImageView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, tempImageView.frame.size.height);
CGContextConcatCTM(context, flipVertical);
[tempImageView.layer renderInContext:context];
UIImage *flippedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return flippedImage;
}
@end
我創建了一個測試項目(在zip)來說明問題:
供將來參考,第Ë溶液是這個代碼的一行:
tempImageView.image = nil;
由於Matic的。
你沒有張貼任何代碼,但考慮到你寫的可能是與自動釋放池一個問題:如果使用「爲」循環,你應該在循環內創建內部自動釋放池,並在每個循環中排空它以確保內部釋放這些對象。 –
我嘗試在@autorelease {}中包裝for循環的內部,但它沒有幫助。有什麼我需要補充來排除它嗎?我認爲這是自動的。謝謝 – Lukas
我通常分配自動釋放池,然後耗盡它,但我認爲這應該做同樣的事情。它是自動的,但它不會簡單地制動你的代碼,並釋放推到自動釋放池的對象,除非你指定。看起來有些東西是保留圖像無論如何..如果可能(並沒有其他作品),嘗試繼承UIImage並重寫保留和釋放方法,以查看哪些對象保留它們。你也使用ARC?是否有可能看到一些相關的代碼? –