【问题标题】:high memory usage when resizing uiimage调整uiimage大小时内存使用率高
【发布时间】:2015-05-04 09:26:18
【问题描述】:

在矩形中调整和绘制 UIImage 时会占用大量内存。

   - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
        UIImage *selectedImage=[info objectForKey:UIImagePickerControllerOriginalImage];

        //  COMPRESSING IMAGE
     NSData   *selectedImageData=UIImageJPEGRepresentation(selectedImage, 0.5);
        UIImage *selectedImageFromData=[UIImage imageWithData:selectedImageData];


        //SCALING UIIMAGE
        UIImage *scaledImage=[[UIImage alloc]init];
        if (((selectedImageFromData.size.width>3264) && (selectedImageFromData.size.height>2448)) || ((selectedImageFromData.size.height>3264) && (selectedImageFromData.size.width>2448)))
        {
           CGFloat originalWidth=selectedImageFromData.size.width;
                CGFloat originalHeight=selectedImageFromData.size.height;
                CGFloat myWidth=2048;
                CGFloat widthRatio=myWidth/originalWidth;
                CGFloat dynamicHeight=widthRatio*originalHeight;

         CGImageRef CoreGraphicsImage=selectedImageFromData.CGImage;
        CGColorSpaceRef colorSpace = CGImageGetColorSpace(CoreGraphicsImage);
        CGBitmapInfo bitmapInfo=CGImageGetBitmapInfo(CoreGraphicsImage);
  CGImageGetBitsPerComponent(CoreGraphicsImage);

        CGContextRef context=CGBitmapContextCreate(NULL, myWidth, dynamicHeight, CGImageGetBitsPerComponent(CoreGraphicsImage), CGImageGetBytesPerRow(CoreGraphicsImage), colorSpace, bitmapInfo);


        CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
        CGContextDrawImage(context, CGRectMake(0, 0, myWidth, dynamicHeight), CoreGraphicsImage);
        CGImageRef CGscaledImage=CGBitmapContextCreateImage(context);
        UIImage *CGLastimage = [UIImage imageWithCGImage: CGscaledImage];


        NSLog(@"%f",CGLastimage.size.width);
        NSLog(@"%f",CGLastimage.size.height);

        VisualEffectImageVIew.image=CGLastimage;
                BackgroundImageView.image=CGLastimage;
                ForegroundImageView.image=CGLastimage;
        }
        else
        {
            NSLog(@" HEIGHT %f",selectedImageFromData.size.height);
            NSLog(@" WIDTH %f",selectedImageFromData.size.width);

        VisualEffectImageVIew.image=selectedImageFromData;
        BackgroundImageView.image=selectedImageFromData;
        ForegroundImageView.image=selectedImageFromData;
        }
       if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
        {
            [picker dismissViewControllerAnimated:YES completion:nil];
        }
        else
        {


            [popoverController dismissPopoverAnimated:YES];

            [self popoverControllerDidDismissPopover:popoverController];
      }

    }

这是下面的图片,在图片中你可以看到上面提到的代码使用了太多的内存。想知道为什么它使用了太多内存,并希望有任何解决方案。

【问题讨论】:

  • 在 UIImage 中加载 JPEG 并不意味着它不必解码图像的每个像素,并将其存储在内存中。仅供参考,3200x2400 像素 = 7.68Mpix,在 RGB(每像素 24 位)中,这产生 184.32MBits,或大约 23Mbytes。
  • 是的,但这与我的问题有什么关系?在这里,我们正在尝试缩小超过 8 兆像素的图像。而且我们不仅会在应用程序崩溃时遇到内存问题。有关更多信息,请查看上图中使用大量内存的代码。
  • 只是说调整百万像素图像的大小需要这么多内存是正常的。正如答案中所述,您绝对应该使用一些优化的库,例如 GPUImage。
  • 到时候我们会调查的。
  • 有没有办法在storyboard中使用GPUImageView?

标签: ios objective-c iphone xcode ios8.1


【解决方案1】:

在图像方面,我一直是Brad Larson's GPUImage 的忠实粉丝,它可以做任何你想做的事情,并且使用 GPU 而不是 CPU,这让你有足够的能力来避免由于内存压力而导致的崩溃。

而且还不错。

This stackoverflow question 还可以帮助您在完成项目设置后实现您想要的。

希望这会有所帮助:)

【讨论】:

    【解决方案2】:

    您使用 CPU 将数据绘制到帧中,我建议您使用 CGImage 在 GPU 上下文中进行绘制

    - (UIImage *) scaleToSize: (CGSize)size
    {
        // Scalling selected image to targeted size
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
        CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height));
    
        if(self.imageOrientation == UIImageOrientationRight)
        {
            CGContextRotateCTM(context, -M_PI_2);
            CGContextTranslateCTM(context, -size.height, 0.0f);
            CGContextDrawImage(context, CGRectMake(0, 0, size.height, size.width), self.CGImage);
        }
        else
            CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), self.CGImage);
    
        CGImageRef scaledImage=CGBitmapContextCreateImage(context);
    
        CGColorSpaceRelease(colorSpace);
        CGContextRelease(context);
    
        UIImage *image = [UIImage imageWithCGImage: scaledImage];
    
        CGImageRelease(scaledImage);
    
        return image;
    }
    

    【讨论】:

    • 看看我们更新的代码,CoreGraphics 速度更快,但内存警告和崩溃现在变得更多。(内存报告显示现在 150 MB 使用量)。调整下一个(第二个)图像大小时应用程序崩溃.我想说的是它现在变得更糟了。
    • 抱歉不快,还是一样
    猜你喜欢
    • 2018-02-14
    • 2014-02-15
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2011-08-17
    • 2021-12-28
    相关资源
    最近更新 更多