1

我有一千张小图片。我需要同时将它们一个一个地组合成一个大图像并在屏幕上生活。无论我们如何加载/组合小图像,用户都应该能够快速流畅地观看显示的小图像。

意思是:

大图像 += 小图像 1;

大图像 += 小图像2;

大图像 += 小图像3;

...

大图像 += 小图像 1000+;

第一次,我只是用 addSubviews/addSublayers 将小图像添加到大图像中。可以想象,这会导致巨大的延迟,因为要渲染的视图太多,成本很高。

所以我尝试只使用一个imageView(大图像),每次将小图像组合成大图像。所以我写了一些代码,比如:

UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0f);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[bgImageView.layer renderInContext:ctx];
//[bgImageView.image drawInRect:self.frame];  // This line or the line above, same result
[smallImg drawInRect:rectToWindow];
bgImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

但是仍然存在巨大的滞后问题(但方式不同),我猜是因为它每次都渲染大图像,成本很高。

所以问题是:

有没有可能我可以保持在上下文中渲染的大图像,而不是每次都渲染它?

或者你有更好的主意可以做我需要的。只要和我谈谈,任何想法都会有所帮助。

感谢你们。

4

3 回答 3

0

如果您正在处理大量图像,那么 OpenGLES 是最佳选择并使用单个 EAGL 视图。

于 2013-02-15T18:26:06.277 回答
0

我认为您的视图应该是的子类,UIImageView当您想将一组小图像添加到大图像时,请使用以下方法:

- (UIImage *)addSmallImages:(NSArray *)smallImages   // array of UIImage
                   atPoints:(NSArray *)points        // array of NSValue
                 toBigImage:(UIImage *)bigImage
{
    if (smallImages.count != points.count)
    {
        NSLog(@"Array size mismatch");
        return nil;
    }

    NSUInteger count = [smallImages count];

    UIGraphicsBeginImageContextWithOptions(bigImage.size, NO, 0.0); 
    [bigImage drawAtPoint:CGPointZero];

    for (NSUInteger i = 0; i < count; i++)
    {
        UIImage *smallImage = [smallImages objectAtIndex:i];
        NSValue *pointVal = [points objectAtIndex:i];
        CGPoint point = [pointVal CGPointValue];
        [smallImage drawAtPoint:point];
    }

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext();
    return newImage; 
}

这被称为这样的东西:

NSMutableArray *smallImages = [[NSMutableArray alloc] init];
NSMutableArray *points = [[NSMutableArray alloc] init];

for (NSUInteger i = 0 ...)
{
    [smallImages addObject:smallImage];
    [points addObject:[NSValue valueWithCGPoint:CGMakePoint(100.0, 120.0)]];
}

imageView.view = [self addSmallImages:smallImages atPoints:points toBigImage:imageView.view];

如果您想将“小图像”动画到“大图像”上,那么您可以通过创建一个CALayer,将“小图像”应用​​到它,然后将其动画到正确的位置来实现。然后调用上述方法提交更改,然后删除图层。

于 2013-02-15T18:45:15.180 回答
0

我的第一个想法是绘制一个 UIViewdrawRect:并每 1/10 秒或类似的东西绘制每个图像。之后,只需使用类似的函数UIGraphicsGetImageFromCurrentImageContext()并将整个上下文保存到图像中。这样图像是动态绘制的(所以即使需要很长时间用户也会看到它发生)。

我的第二个想法是在CGBitmapContext后台线程上绘制一个并在绘制时添加一个活动指示器。

于 2013-02-15T18:46:01.537 回答