- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我不确定我的标题是否完全正确,但我不确定我的问题到底出在哪里。
我需要从 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 ,它会显示加载时间花在哪里
最佳答案
好吧,我终于知道问题出在哪里了。在使用 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/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 7 年前。 Improve
我正在使用 SDL2 用 C 语言开发游戏,我的问题是该游戏是全高清的,并且具有长(180 帧)角色动画,会生成非常大的 Sprite 表。我有一个 7326x7250px 的 Sprite 表,我必
我有一个 spritesheet (9170px x 350px),其中包含 70 帧单个字符。这是我的代码。 @-webkit-keyframes play { 100% { backg
我在纹理打包器的帮助下生成了一个 CSS Spritesheet,它看起来像 .pirateSlotSprite {display:inline-block; overflow:hidden; bac
“简单”问题。 为站点元素使用大型 spritesheet 是否比使用多张图片更好? 我的意思是,额外的 CSS 图像处理(背景定位大图像并裁剪它)是否弥补了较少的 HTTP 图像请求? 最佳答案 n
我到处都能找到有关如何使用从 zwoptex 创建的文件运行动画的代码,但它使用的是已弃用的代码。我找不到有关如何使用 CCSpriteBatchNode 运行动画的代码。 有什么建议吗? 最佳答案
我有一个小问题,我使用的是多行 Spritesheet,其中每一行都是图像序列。 但是我无法让 Sprite 表从不同的高度开始(因此它可以向下移动),它们都从顶 Angular 开始 var sp
尝试在我的游戏中添加爆炸动画,但由于某种原因只播放 Sprite 的第一帧。 Spritesheet 在预加载器中加载。 这是调用动画的函数 function asteroidCollisionHan
我有一个 spritesheet 驱动一组按钮的外观,这些按钮会根据各种鼠标操作而变化。但是,在 sprite 之间切换时我可以看到闪烁,并且在 chrome 或 firebug 中查看网络面板确认每
目前,我有一个菜单场景,我在其中将 spritesheet 添加到帧缓存中。我反复离开菜单场景并返回。因此,每次重新加载菜单场景时,都会将相同的 spritesheet 添加到帧缓存中。这是坏事吗?旧
我创建了一个 spritesheet;在桌面上一切正常。但是,然后我尝试在我的 iPhone 5s 上查看它,它显示正常,但是当单击图像时,会立即出现一个深灰色框。我立即想到也许我有冲突的 CSS,但
我有一个描述 Sprite 表中 Sprite 的 xml 文件:
下面的代码片段应该播放 1-3 帧 3 次,并且(在我看来)在第 3 帧结束,而不是在完成后显示第 4 帧,这在之前的 3 次迭代中没有动画。 由于这在 Chrome、Safari 和 FF 中同样有
我有一个 Sprite 表,宽度为 5760 像素,高度为 5400 像素,包含 10 行和 6 列,每列宽度为 960 像素,高度为 540 像素。 Sprite 表中的所有 Sprite 都是从左
所以我为我正在制作的游戏制作了一个 sprite 表动画,但由于某种原因它远远落后于我的游戏。 Sprite 表是一个 1248x120 .png 文件,每个 Sprite 的大小为 156x120
我正在尝试使用 spritesheet 制作 Logo 动画,效果很好。代码就像 #logo { background: url('../img/logo.png'); height: 142
我的游戏有问题,这不是错误而是问题。我正在使用 spritesheets 来制作我的游戏并使用 for 循环自动调用我的 Platform 类。但是,当我尝试调用平台类时,它只显示整个 sprites
我想为我的图标使用 CSS Spritesheet。每个图标图像的大小为 48x48px。但是,我希望能够显示任意尺寸的图标。 现在,我正在使用,显示一个 24x24 图标,我使用: 有没有更短
我正在使用 Python 和 Pygame 开发游戏。我为其中一个敌人创建了一个 sprite 表,并让它运行了我的代码。问题是图像看起来有黑色背景,即使它是透明图像。它的代码是这样的: en
我正在尝试从 spritesheet 中选择背景图像的一部分,填充其容器中的整个空间。 在这支笔中,背景图像应始终填充字符。也在调整大小时,这是主要问题。 https://codepen.io/tim
我是一名优秀的程序员,十分优秀!