有人能帮我解决这个问题吗?我对objective 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;
}可能是一个内存管理。我将感谢你的帮助
发布于 2013-09-28 07:47:47
使用您的fixRotation方法是正确的。但是,您还应该对图像进行大小调整。否则,图像将很大,约为30MB(取决于设备)。
查看this blog post,了解如何正确调整图像大小。具体来说,您需要的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...
});
});
}发布于 2013-10-25 18:22:36
UIImageWriteToSavedPhotosAlbum方法在IOS7上使用30M+内存,这与调整大小或固定旋转方法无关。
发布于 2014-02-18 17:23:34
我已经通过JRG-Developer-s答案修复了这个问题,只做了一点修改:我正在使用类别来修复图像的方向,并在演示之前缩小它,完成后,我调用弱自我将这个缩放和固定的图像分配到我的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的空间--我不得不一张接一张地拍两张照片……现在,它工作得很好,很流畅。固定方向是可选的,但我还是建议你缩小图片大小,让它变小。
https://stackoverflow.com/questions/19061510
复制相似问题