10

有沒有人可以幫我解決這個問題我對目標C和iOS有點新。我一直在努力,但我無法弄清楚如何解決這個問題,我的應用程序非常簡單,它只啓動相機拍照並通過電子郵件發送給我們的服務器。這段代碼在iOS6中工作得很好。內存警告UIImagepickerController IOS 7

當我拍照時,我的記憶是每個屏幕捕捉的堆積增長,並且我收到「接收到的內存警告」,最後 - 由於內存壓力而終止。 -

-(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

運行靜態分析器查看是否有任何警告。然後在樂器中運行應用程序,查找任何泄漏並保留週期。 – rmaddy

回答

7

你正處於正確的軌道與你的fixRotation方法。不過,您還應該調整大小的形象。否則,圖像會很大,〜30 MB(取決於設備)。

結帳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... 
     });   
    }); 
} 
+0

我已調整大小,內存增加減少,但它繼續增加一點點,直到我的應用程序崩潰,以某種方式,我需要清除內存 –

+0

首先,我說了一個新的項目與iOS7具有相同的類和方法,最後我將圖像大小調整爲640 x 480和480 x 640,然後應用了fixRotation方法,我的記憶增加了一次,但與其他照片沒有增加。 –

+0

@cesartrujillocetina你能展示你的最終工作代碼嗎?我有同樣的問題。 – Danpe

4

UIImageWriteToSavedPhotosAlbum方法使用30M +內存iOS7.It東西不是你的大小或fixrotation方法。

+0

我有同樣的問題,並調整圖像doens't工作... – Ladessa

+0

我也有同樣的問題..是任何一個得到的解決方案? – Sabareesh

+0

是的,每當我打電話給UIImageWriteToSavedPhotosAlbum時,我的應用程序都會收到內存警告!而且顯然崩潰! –

1

我已經JRG-開發-S答案在這裏 少許改動修復了這個問題: 我`使用類別來修復圖像的方向中號ANS呈現 之前比例縮小完成後,我打電話弱自我此縮放和定影圖像分配到我的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; 
} 

請不要-T是殘酷的minusing如果事情看起來虛擬)林初中現在)

對於下面的答案 - 這就是爲什麼你會更好地縮小圖像 - 使用較少的內存,但不是簡單地將大4MB圖像保存到光盤。在剛開始的時候,我也有記憶問題 - 每張單張照片吃了30Mb - 我不得不逐一拍攝2張照片......現在它工作得很好,很順利。 修復方向是可選的,但我會建議無論如何縮小照片 - 調整到較小。