10

Qualcuno potrebbe aiutarmi con questo problema Sono un po 'nuovo all'obiettivo c e iOS. Ci sto lavorando ma non riesco a capire come risolvere il problema, la mia app è davvero semplice, si avvia solo la fotocamera scattare foto e inviarle tramite e-mail al nostro server. Questo codice funzionava bene su iOS6.Memory Warning UIImagepickerController IOS 7

Quando scatto la mia memoria è un mucchio di crescita con ogni acquisizione dello schermo e ricevo "Avviso memoria ricevuta" e infine - Terminato a causa della pressione di memoria. -

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


} 

probabilmente è una gestione della memoria. Apprezzerò il tuo aiuto

+0

Eseguire l'analizzatore statico per verificare se sono presenti avvisi. Quindi esegui l'app in Strumenti e cerca eventuali perdite e conserva i cicli. – rmaddy

risposta

7

Sei sulla strada giusta con il tuo metodo fixRotation. Tuttavia, si dovrebbe anche ridimensionare l'immagine. Altrimenti, l'immagine sarà enorme, ~ 30 MB (a seconda del dispositivo).

Checkout this blog post su come ridimensionare correttamente le immagini. In particolare, i file UIImage categoria desiderata sono questi:

UIImage+Resize.h

UIImage+Resize.m

E 'anche una buona idea per fare questo su un thread in background. Qualcosa di simile

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

l'ho ridimensionato, l'aumento della memoria è stato ridotto, ma continua ad aumentare un po 'più lentamente fino all'arresto della mia app, in qualche modo ho bisogno di pulire la memoria –

+0

Prima di tutto ho dichiarato un nuovo progetto con iOS7 con le stesse Classi e metodi e infine Ho ridimensionato le immagini a 640 x 480 e 480 X 640 e poi ho applicato il metodo fixRotation, la mia memoria aumenta una volta ma con altre foto no. –

+0

@cesartrujillocetina Puoi mostrare il tuo codice di lavoro finale? Sto avendo lo stesso problema. – Danpe

4

metodo UIImageWriteToSavedPhotosAlbum uso 30M + memoria sul iOS7.It non si tratta di tuo ridimensionamento o fixrotation metodo.

+0

Ho lo stesso problema e ridimensiono l'immagine non funziona ... – Ladessa

+0

Ho anche lo stesso problema .. c'è qualcuno che ha una soluzione? – Sabareesh

+0

Sì amico, ogni volta che chiamo UIImageWriteToSavedPhotosAlbum la mia app riceve un avviso di memoria !! E ovviamente crash! –

1

ho fissato questo problema risposta qui con piccole modifiche JRG-Developer-s: I `m utilizzando categorie per correggere l'orientamento dell'immagine ans ridimensionamento verso il basso prima di presentare e una volta fatto, mi chiamo Debole Auto assegnare questa immagine scalata e fissa nella mia 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]; 
    } 
} 

e inferiore:

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

codice di scalatura è stata presa dalla rete:

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

e il codice per cambiare (fissaggio) orientamento dell'immagine è stata assunta anche dalla rete:

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

per favore, don-t essere crudele in minusing se qualcosa sembra fittizio) Im Junior per ora)

Per la risposta qui sotto - ecco perché è meglio ridimensionare un'immagine - per utilizzare meno memoria, ma non semplicemente salvare la grande immagine da 4 MB sul disco. All'inizio ho anche avuto problemi di memoria - stava mangiando 30Mb per foto sigle - e ho dovuto prendere 2 foto una per una ... ora funziona bene e liscio. L'orientamento fisso è facoltativo, ma io consiglio comunque di ridimensionare la foto: ridimensionarla a dimensioni inferiori.

Problemi correlati