3

My app displays a bunch of images in a UICollectionView. When I call:

[UIImage imageWithContentsOfFile:thumbnailPath];

my app uses around 60mb of RAM for my test set of images.

However, when I then do the following:

  UIImage* image = [UIImage imageWithContentsOfFile:thumbnailPath];

  // Pre-render the image to ensure there isn't lag later.
  CGSize imageSize = image.size;
  UIGraphicsBeginImageContext(imageSize);
  [image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
  UIImage* preRenderedImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();

  return preRenderedImage;

It is down to only around 15mb of RAM.

The image scale is 1.0 before and and after the pre-rendering, and size is the same, so I'm not sure what accounts for the difference in memory usage. I also tried using UIGraphicsBeginImageContextWithOptions(imageSize, NO, 2.0); which made no difference in memory usage.

Similar: Why does my UIImage take up so much memory?

Update

Here is a dump of the image info:

----- original -------
CGImageGetHeight: 1024
CGImageGetWidth:  768
CGImageGetColorSpace: <CGColorSpace 0x174222e20> (kCGColorSpaceDeviceRGB)
CGImageGetBitsPerPixel:     32
CGImageGetBitsPerComponent: 8
CGImageGetBytesPerRow:      4096
CGImageGetBitmapInfo: 0x00000005
  kCGBitmapAlphaInfoMask     = YES
  kCGBitmapFloatComponents   = NO
  kCGBitmapByteOrderMask     = 0x00000000
  kCGBitmapByteOrderDefault  = YES
  kCGBitmapByteOrder16Little = NO
  kCGBitmapByteOrder32Little = NO
  kCGBitmapByteOrder16Big    = NO
  kCGBitmapByteOrder32Big    = NO

----- pre-rendererd -------
CGImageGetHeight: 1024
CGImageGetWidth:  768
CGImageGetColorSpace: <CGColorSpace 0x174222e20> (kCGColorSpaceDeviceRGB)
CGImageGetBitsPerPixel:     32
CGImageGetBitsPerComponent: 8
CGImageGetBytesPerRow:      4096
CGImageGetBitmapInfo: 0x00002002
  kCGBitmapAlphaInfoMask     = YES
  kCGBitmapFloatComponents   = NO
  kCGBitmapByteOrderMask     = 0x00002000
  kCGBitmapByteOrderDefault  = NO
  kCGBitmapByteOrder16Little = NO
  kCGBitmapByteOrder32Little = YES
  kCGBitmapByteOrder16Big    = NO
  kCGBitmapByteOrder32Big    = NO

Note the difference in byte order, which makes sense because png files are big endian (PNG file format endianness?). Could the endianness be causing the excess memory usage (presumably because of a conversion before drawing)? It would be a surprise because PNGs are used all over in an iOS app.

Community
  • 1
  • 1
Taylor
  • 5,871
  • 2
  • 30
  • 64

0 Answers0