【问题标题】:Need a solution to combine an amount of images one by one on the screen需要一种解决方案来在屏幕上一张一张地组合大量图像
【发布时间】:2013-02-15 18:23:58
【问题描述】:

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

这意味着:

大图像 += 小图像1;

大图像 += 小图像2;

大图像 += 小图像3;

...

BigImage += SmallImage1000+;

第一次,我只是用 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();

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

所以问题是:

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

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

谢谢你们。

【问题讨论】:

    标签: ios performance uiimageview cgcontext composite


    【解决方案1】:

    我认为您的视图应该是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,将“小图像”应用​​到它,然后将其动画到正确的位置来实现。然后调用上面的方法提交修改,然后移除图层。

    【讨论】:

    • 感谢您的回复,但我看不出您的回答与我所做的有什么区别。我很抱歉我在我的问题中犯了错误:“一个接一个”不准确,应该是“几十个”。我将编辑问题。
    • @swang 请看我的更新;您没有描述您的视图是如何工作的以及“大图像”是如何存储的,但我认为它应该是一个 UIImageView 子类并且可以正常工作。
    • 是的,“大图”是UIImageView。抱歉我的糟糕描述,我再次重新编辑问题:无论我们如何加载/组合小图像,用户都应该能够快速流畅地观看显示的小图像
    【解决方案2】:

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

    【讨论】:

    • 感谢您的回复。我没有太多的OpenGLES。你有一些代码或例子吗?
    • 您可以在 iOS SDK 中获得许多 OpenGLES 示例。 - GLES2Sample、GLEssentials、GLImageProcessing、GLPaint、GLSprite、GLTextureAtlas。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多