I use this piece of code to scale and rotate images taken with the camera. When I use this, I see a huge peak of memory. Something like 20 MB. When I use the tools, I see that this line:
CGContextDrawImage (ctxt, orig, self.CGImage);
has a value of 20 MB. Is this normal for full resolution photos? The iPhone 4S can handle this. but this code crashes old devices.
After I rescale the image I need in NSData, I use the UIImageJPEGRepresentation () method. This together makes the peak of memory even higher. It takes up to 70 MB in memory in a few seconds.
And yes, I read almost the entire question related to the iOS camera regarding memory usage. But there is no answer.
// WBImage.mm -- extra UIImage methods // by allen brunson march 29 2009 #include "WBImage.h" static inline CGFloat degreesToRadians(CGFloat degrees) { return M_PI * (degrees / 180.0); } static inline CGSize swapWidthAndHeight(CGSize size) { CGFloat swap = size.width; size.width = size.height; size.height = swap; return size; } @implementation UIImage (WBImage) // rotate an image to any 90-degree orientation, with or without mirroring. // original code by kevin lohman, heavily modified by yours truly. // http://blog.logichigh.com/2008/06/05/uiimage-fix/ -(UIImage*)rotate:(UIImageOrientation)orient { CGRect bnds = CGRectZero; UIImage* copy = nil; CGContextRef ctxt = nil; CGRect rect = CGRectZero; CGAffineTransform tran = CGAffineTransformIdentity; bnds.size = self.size; rect.size = self.size; switch (orient) { case UIImageOrientationUp: return self; case UIImageOrientationUpMirrored: tran = CGAffineTransformMakeTranslation(rect.size.width, 0.0); tran = CGAffineTransformScale(tran, -1.0, 1.0); break; case UIImageOrientationDown: tran = CGAffineTransformMakeTranslation(rect.size.width, rect.size.height); tran = CGAffineTransformRotate(tran, degreesToRadians(180.0)); break; case UIImageOrientationDownMirrored: tran = CGAffineTransformMakeTranslation(0.0, rect.size.height); tran = CGAffineTransformScale(tran, 1.0, -1.0); break; case UIImageOrientationLeft: bnds.size = swapWidthAndHeight(bnds.size); tran = CGAffineTransformMakeTranslation(0.0, rect.size.width); tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0)); break; case UIImageOrientationLeftMirrored: bnds.size = swapWidthAndHeight(bnds.size); tran = CGAffineTransformMakeTranslation(rect.size.height, rect.size.width); tran = CGAffineTransformScale(tran, -1.0, 1.0); tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0)); break; case UIImageOrientationRight: bnds.size = swapWidthAndHeight(bnds.size); tran = CGAffineTransformMakeTranslation(rect.size.height, 0.0); tran = CGAffineTransformRotate(tran, degreesToRadians(90.0)); break; case UIImageOrientationRightMirrored: bnds.size = swapWidthAndHeight(bnds.size); tran = CGAffineTransformMakeScale(-1.0, 1.0); tran = CGAffineTransformRotate(tran, degreesToRadians(90.0)); break; default: // orientation value supplied is invalid assert(false); return nil; } UIGraphicsBeginImageContext(rect.size); ctxt = UIGraphicsGetCurrentContext(); switch (orient) { case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: case UIImageOrientationRight: case UIImageOrientationRightMirrored: CGContextScaleCTM(ctxt, -1.0, 1.0); CGContextTranslateCTM(ctxt, -rect.size.height, 0.0); break; default: CGContextScaleCTM(ctxt, 1.0, -1.0); CGContextTranslateCTM(ctxt, 0.0, -rect.size.height); break; } CGContextConcatCTM(ctxt, tran); CGContextDrawImage(ctxt, bnds, self.CGImage); copy = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return copy; } -(UIImage*)rotateAndScaleFromCameraWithMaxSize:(CGFloat)maxSize { UIImage* imag = self; imag = [imag rotate:imag.imageOrientation]; imag = [imag scaleWithMaxSize:maxSize]; return imag; } -(UIImage*)scaleWithMaxSize:(CGFloat)maxSize { return [self scaleWithMaxSize:maxSize quality:kCGInterpolationHigh]; } -(UIImage*)scaleWithMaxSize:(CGFloat)maxSize quality:(CGInterpolationQuality)quality { CGRect bnds = CGRectZero; UIImage* copy = nil; CGContextRef ctxt = nil; CGRect orig = CGRectZero; CGFloat rtio = 0.0; CGFloat scal = 1.0; bnds.size = self.size; orig.size = self.size; rtio = orig.size.width / orig.size.height; if ((orig.size.width <= maxSize) && (orig.size.height <= maxSize)) { return self; } if (rtio > 1.0) { bnds.size.width = maxSize; bnds.size.height = maxSize / rtio; } else { bnds.size.width = maxSize * rtio; bnds.size.height = maxSize; } UIGraphicsBeginImageContext(bnds.size); ctxt = UIGraphicsGetCurrentContext(); scal = bnds.size.width / orig.size.width; CGContextSetInterpolationQuality(ctxt, quality); CGContextScaleCTM(ctxt, scal, -scal); CGContextTranslateCTM(ctxt, 0.0, -orig.size.height); CGContextDrawImage(ctxt, orig, self.CGImage); copy = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return copy; } @end