内存警告UIImagepickerController IOS 7

任何人都可以帮我解决这个问题我对目标c和iOS有点新意。 我一直在努力,但我无法弄清楚如何解决问题,我的应用程序非常简单,它只是启动相机拍照并通过电子邮件发送到我们的服务器。 这段代码在iOS6中运行得很好。

当我拍照时,我的内存是每次屏幕捕获的堆增长,我得到“接收内存警告”,最后 – 由于内存压力终止。 –

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { [self.popoverController2 dismissPopoverAnimated:true]; NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType]; if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) { _image = [info objectForKey:UIImagePickerControllerOriginalImage]; _image = [self fixrotation:_image]; //<----- increased memory when UIImageWriteToSavedPhotosAlbum is uncommented IF is comment it doesn't increased memory but after some pictures I start to get "Received Memory Warning" message until the app Crash. if (_newMedia){ UIImageWriteToSavedPhotosAlbum(_image, self,@selector(image:finishedSavingWithError:contextInfo:), nil); [self dismissViewControllerAnimated:NO completion:nil]; [self performSegueWithIdentifier:@"SeleccionadoCameraR" sender:self]; }else{ [self performSegueWithIdentifier:@"SeleccionadoCameraR" sender:self]; } } } - (UIImage *)fixrotation:(UIImage *)image{ if (image.imageOrientation == UIImageOrientationUp) return image; CGAffineTransform transform = CGAffineTransformIdentity; switch (image.imageOrientation) { case UIImageOrientationDown: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: transform = CGAffineTransformTranslate(transform, image.size.width, 0); transform = CGAffineTransformRotate(transform, M_PI_2); break; case UIImageOrientationRight: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, 0, image.size.height); transform = CGAffineTransformRotate(transform, -M_PI_2); break; case UIImageOrientationUp: case UIImageOrientationUpMirrored: break; } switch (image.imageOrientation) { case UIImageOrientationUpMirrored: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, image.size.width, 0); transform = CGAffineTransformScale(transform, -1, 1); break; case UIImageOrientationLeftMirrored: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, image.size.height, 0); transform = CGAffineTransformScale(transform, -1, 1); break; case UIImageOrientationUp: case UIImageOrientationDown: case UIImageOrientationLeft: case UIImageOrientationRight: break; } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height, CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage)); CGContextConcatCTM(ctx, transform); switch (image.imageOrientation) { case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: case UIImageOrientationRight: case UIImageOrientationRightMirrored: // Grr... CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage); break; default: CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.CGImage); //when I use instruments it shows that My VM is because of this break; } // And now we just create a new UIImage from the drawing context CGImageRef cgimg = CGBitmapContextCreateImage(ctx);//also this line in Instruments UIImage *img = [UIImage imageWithCGImage:cgimg]; CGContextRelease(ctx); CGImageRelease(cgimg); return img; } 

可能是内存管理。 我将非常感谢你的帮助

您正在使用fixRotation方法fixRotation 。 但是,您还应该调整图像大小 。 否则,图像将是巨大的,约30 MB(取决于设备)。

查看此博客文章 ,了解如何正确调整图像大小。 具体来说,您想要的UIImage类别文件是:

的UIImage + Resize.h

的UIImage + Resize.m

在后台线程上执行此操作也是一个好主意。 像这样的东西

 - (void)imagePickerController:(UIImagePickerController *)imagePicker didFinishPickingMediaWithInfo:(NSDictionary *)info { // Dismiss the image picker first to free its memory [self dismissViewControllerAnimated:YES completion:nil]; UIImage *originalImage = info[UIImagePickerControllerOriginalImage]; if (!originalImage) return; // Optionally set a placeholder image here while resizing happens in background dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // Set desired maximum height and calculate width CGFloat height = 640.0f; // or whatever you need CGFloat width = (height / originalImage.size.height) * originalImage.size.width; // Resize the image UIImage * image = [originalImage resizedImage:CGSizeMake(width, height) interpolationQuality:kCGInterpolationDefault]; // Optionally save the image here... dispatch_async(dispatch_get_main_queue(), ^{ // ... Set / use the image here... }); }); } 

UIImageWriteToSavedPhotosAlbum方法在iOS7上使用30M +内存。这不是关于你的resize或fixrotation方法。

我已经通过JRG-Developer-s解决了这个问题,稍作修改:我使用类别来修复图像的方向,然后在呈现之前缩小它,完成之后,我调用Weak Self来分配这个缩放和固定的图像到我的imageview)

 -(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage *lvImage = [info objectForKey:UIImagePickerControllerOriginalImage]; //CGSize pickedImageSize = lvImage.size; if (postHandler == nil) { postHandler = [[PostHandler alloc] init]; } //_postItemImageView.image = lvImage; //postHandler.wholeScreenImage = lvImage;// to proceed editing, cropping, tagging ... //_postItemImageView.image = postHandler.wholeScreenImage; set in viewWillAppear __weak PostPrepareViewController *weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ { // Resize the image UIImage * scaledImage = [[lvImage imageByScalingAndCroppingForSize:_postItemImageView.frame.size] fixOrientation]; // Optionally save the image here... //CGSize scaledimageSize = scaledImage.size; dispatch_async(dispatch_get_main_queue(), ^ { postHandler.wholeScreenImage = scaledImage; [weakSelf didScaleDownImage]; }); }); if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { [self.popOver dismissPopoverAnimated:YES]; } else { [self dismissViewControllerAnimated:YES completion:nil]; } } 

并降低:

 -(void) didScaleDownImage { _postItemImageView.image = postHandler.wholeScreenImage; } 

缩放代码取自网络:

 -(UIImage *)imageByScalingAndCroppingForSize:(CGSize)targetSize { UIImage *sourceImage = self; UIImage *newImage = nil; CGSize imageSize = sourceImage.size; CGFloat width = imageSize.width; CGFloat height = imageSize.height; CGFloat targetWidth = targetSize.width; CGFloat targetHeight = targetSize.height; CGFloat scaleFactor = 0.0; CGFloat scaledWidth = targetWidth; CGFloat scaledHeight = targetHeight; CGPoint thumbnailPoint = CGPointMake(0.0,0.0); if (CGSizeEqualToSize(imageSize, targetSize) == NO) { CGFloat widthFactor = targetWidth / width; CGFloat heightFactor = targetHeight / height; if (widthFactor > heightFactor) { scaleFactor = widthFactor; // scale to fit height } else { scaleFactor = heightFactor; // scale to fit width } scaledWidth = width * scaleFactor; scaledHeight = height * scaleFactor; // center the image if (widthFactor > heightFactor) { thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; } else { if (widthFactor < heightFactor) { thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; } } } UIGraphicsBeginImageContext(targetSize); // this will crop //UIGraphicsBeginImageContextWithOptions(targetSize, 1.0, 0.0); CGRect thumbnailRect = CGRectZero; thumbnailRect.origin = thumbnailPoint; thumbnailRect.size.width = scaledWidth; thumbnailRect.size.height = scaledHeight; [sourceImage drawInRect:thumbnailRect]; newImage = UIGraphicsGetImageFromCurrentImageContext(); if(newImage == nil) { NSLog(@"could not scale image"); } //pop the context to get back to the default UIGraphicsEndImageContext(); return newImage; } 

用于更改(固定)图像方向的代码也来自网络:

 - (UIImage *)fixOrientation { // No-op if the orientation is already correct if (self.imageOrientation == UIImageOrientationUp) return self; // We need to calculate the proper transformation to make the image upright. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. CGAffineTransform transform = CGAffineTransformIdentity; switch (self.imageOrientation) { case UIImageOrientationDown: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, 0); transform = CGAffineTransformRotate(transform, M_PI_2); break; case UIImageOrientationRight: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, 0, self.size.height); transform = CGAffineTransformRotate(transform, -M_PI_2); break; default: break; } switch (self.imageOrientation) { case UIImageOrientationUpMirrored: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, 0); transform = CGAffineTransformScale(transform, -1, 1); break; case UIImageOrientationLeftMirrored: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, self.size.height, 0); transform = CGAffineTransformScale(transform, -1, 1); break; default: break; } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height, CGImageGetBitsPerComponent(self.CGImage), 0, CGImageGetColorSpace(self.CGImage), CGImageGetBitmapInfo(self.CGImage)); CGContextConcatCTM(ctx, transform); switch (self.imageOrientation) { case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: case UIImageOrientationRight: case UIImageOrientationRightMirrored: // Grr... CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage); break; default: CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage); break; } // And now we just create a new UIImage from the drawing context CGImageRef cgimg = CGBitmapContextCreateImage(ctx); CGContextRelease(ctx); UIImage *img = [UIImage imageWithCGImage:cgimg]; CGImageRelease(cgimg); // return img; } 

如果看起来很虚假的话,请不要吝啬。我现在是大三)

对于下面的答案 - 这就是为什么你要更好地缩小图像 - 为了减少使用中的内存,而不是简单地将大4MB图像保存到光盘。 在一开始我也有记忆问题 - 每张照片吃30Mb - 而且我不得不逐张拍摄2张照片......现在它工作得非常顺畅。 修复方向是可选的,但我建议无论如何缩小照片 - 将其调整为更小。