我正在尝试编写一个采用PNG图块集的iPhone应用程序,并在屏幕上显示它们的片段,我正试图让它以20fps刷新整个屏幕。目前我在模拟器上管理大约3或4fps,在设备上管理0.5到2fps(iPhone 3G),具体取决于屏幕上的内容。
我目前正在使用Core Graphics,目前正试图找到避免咬弹和重构OpenGL的方法。我已经对代码进行了Shark时间配置文件分析,大约70-80%正在进行的所有事情都归结为一个名为copyImageBlockSetPNG的函数,该函数是从CGContextDrawImage中调用的,CGContextDrawImage本身正在调用各种其他函数。 PNG的名称。 Inflate也在那里,占其中的37%。
问题是,我已经将图像从UIImage加载到内存中了,为什么代码仍然关心它是一个PNG?是否在加载时不解压缩为本机未压缩格式?我可以自己转换吗?分析意味着每当我从中绘制一个部分时,它就会对图像进行解压缩,最终会出现一帧的30次或更多次。
-(CGImageRef)inflate:(CGImageRef)compressedImage
{
size_t width = CGImageGetWidth(compressedImage);
size_t height = CGImageGetHeight(compressedImage);
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
int bitmapByteCount;
int bitmapBytesPerRow;
bitmapBytesPerRow = (width * 4);
bitmapByteCount = (bitmapBytesPerRow * height);
colorSpace = CGColorSpaceCreateDeviceRGB();
context = CGBitmapContextCreate (NULL,
width,
height,
8,
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease( colorSpace );
CGContextDrawImage(context, CGRectMake(0, 0, width, height), compressedImage);
CGImageRef result = CGBitmapContextCreateImage(context);
CFRelease(context);
return result;
}
它基于zneak的代码(因此他获得了大奖)但我已经将一些参数更改为CGBitmapContextCreate,以便在我将PNG图像提供给它时停止崩溃。
答案 0 :(得分:4)
为了回答你的上一个问题,你的经验案例似乎证明一旦加载就不会解压缩。
要将它们转换为未压缩的数据,您可以在CGBitmapContext中绘制它们(一次)并从中获取CGImage。它应该是未压缩的。
我不应该这样做:
CGImageRef Inflate(CGImageRef compressedImage)
{
size_t width = CGImageGetWidth(compressedImage);
size_t height = CGImageGetHeight(compressedImage);
CGContextRef context = CGBitmapContextCreate(
NULL,
width,
height,
CGImageGetBitsPerComponent(compressedImage),
CGImageGetBytesPerRow(compressedImage),
CGImageGetColorSpace(compressedImage),
CGImageGetBitmapInfo(compressedImage)
);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), compressedImage);
CGImageRef result = CGBitmapContextCreateImage(context);
CFRelease(context);
return result;
}
不要忘记释放完成后获得的CGImage。
答案 1 :(得分:0)
这个问题完全救了我的一天!谢谢!!虽然我不确定问题出在哪里,但我遇到了这个问题。 Speed up UIImage creation from SpriteSheet
我想补充一点,还有另一种方法可以直接加载图像解压缩,qithout必须写入上下文。
NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
forKey:(id)kCGImageSourceShouldCache];
NSData *imageData = [NSData dataWithContentsOfFile:@"path/to/image.png"]];
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)(imageData), NULL);
CGImageRef atlasCGI = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)dict);
CFRelease(source);
我相信这种方式有点快。希望它有所帮助!