任何人都可以帮我解决这个问题我对目标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;
}
可能是内存管理。我将非常感谢您的帮助
答案 0 :(得分:7)
您使用fixRotation
方法走在正确的轨道上。但是,您还应调整大小图像。否则,图像将是巨大的,约30 MB(取决于设备)。
结帐this blog post,了解如何正确调整图片大小。具体来说,您需要的UIImage
类别文件是:
在后台线程上执行此操作也是个好主意。像这样的东西
- (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...
});
});
}
答案 1 :(得分:4)
UIImageWriteToSavedPhotosAlbum方法在iOS7上使用30M +内存。这不是关于你的resize或fixrotation方法。
答案 2 :(得分:1)
我已经通过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张照片......现在它工作得非常顺畅。 修正方向是可选的,但我建议无论如何缩小照片 - 将其调整为较小的尺寸。