gpt4 book ai didi

ios - 加速从 SpriteSheet 创建 UIImage

转载 作者:搜寻专家 更新时间:2023-10-30 20:19:44 26 4
gpt4 key购买 nike

我不确定我的标题是否完全正确,但我不确定我的问题到底出在哪里。

我需要从 spritesheet 加载一组 UIImages,然后将其用作 UIImageView 中的动画。

spritesheet 是使用 TexturePacker 生成的,它会生成巨大的图集 (2048x2048) 和带有 sprites 描述的 json。

到现在为止,我一直没有遇到任何问题,甚至在 0.5-0.8 秒内加载了 100 帧,这让我非常满意。

问题是现在我需要从 Documents 文件夹加载 spritesheet(它们是下载的,所以不能集成到应用程序中),所以我必须使用 UIImage imageWithContentsOfFile 而不是 UIImage imagenamed.这使我的加载时间增加了 5-15 秒,具体取决于动画中的帧数。我猜问题是因为图像没有被缓存,正在为每一帧加载它,但我不明白为什么

这是代码:

// With this line, perfect
//UIImage *atlas = [UIImage imageNamed:@"media/spritesheets/default-pro7@2x.png"];
// But with this one, incredibly looooong loading times
UIImage *atlas = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"media/spritesheets/default-pro7@2x" ofType:@"png"]];

CGImageRef atlasCGI = [atlas CGImage];

for( NSDictionary* dict in frames) {

NSDictionary *frame = [dict objectForKey:@"frame"];
int x = [[frame objectForKey:@"x"] intValue];
int y = [[frame objectForKey:@"y"] intValue];
int width = [[frame objectForKey:@"w"] intValue];
int height = [[frame objectForKey:@"h"] intValue];

NSDictionary *spriteSize = [dict objectForKey:@"spriteSourceSize"];
int realx = [[spriteSize objectForKey:@"x"] intValue];

NSDictionary *size = [dict objectForKey:@"sourceSize"];
int realWidth = [[size objectForKey:@"w"] intValue];
int realHeight = [[size objectForKey:@"h"] intValue];

//Initialize the canvas size!
canvasSize = CGSizeMake(realWidth, realHeight);

bitmapBytesPerRow = (canvasSize.width * 4);
bitmapByteCount = (bitmapBytesPerRow * canvasSize.height);

bitmapData = malloc( bitmapByteCount );

//Create the context
context = CGBitmapContextCreate(bitmapData, canvasSize.width, canvasSize.height, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);

// Clear background
CGContextClearRect(context,CGRectMake(0.0f,0.0f,canvasSize.width,canvasSize.height));

// Get spriteRect
CGRect cropRect = CGRectMake(x, y, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect(atlasCGI, cropRect);

//Draw the image into the bitmap context
CGContextDrawImage(context, CGRectMake(realx, 0, width, height), imageRef);

//Get the result image
resultImage = CGBitmapContextCreateImage(context);

UIImage *result = result = [UIImage imageWithCGImage:resultImage];

[images addObject:result];

//Cleanup
free(bitmapData);
CGImageRelease(resultImage);
CGImageRelease(imageRef);
}

我什至可以尝试上传系统分析器 session ,它会显示加载时间花在哪里

enter image description here

最佳答案

好吧,我终于知道问题出在哪里了。在使用 Instruments Time profiler 仔细查看之后,我注意到在 copyImageBlockSetPNG 上花费了很多时间,这让我首先相信我正在为每一帧从磁盘加载图像。结果,有人已经遇到了这个问题Does CGContextDrawImage decompress PNG on the fly? ,最后我确实在每一帧加载内存,而不是从磁盘加载内存,而是每一帧都以 png 格式从内存中解压缩。

在那篇文章中有一个解决方案,包括将图像写入上下文并从中获取图像的未压缩副本。

这行得通,但我发现了其他我认为效率更高的方法

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);

希望对您有所帮助!

关于ios - 加速从 SpriteSheet 创建 UIImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15303053/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com