10

Könnte jemand mir bei diesem Problem helfen? Ich bin ein wenig neu bei objective c und iOS. Ich habe daran gearbeitet, aber ich kann nicht herausfinden, wie das Problem zu beheben, Meine App ist wirklich einfach, es nur starten Sie die Kamera Bilder machen und senden Sie sie per E-Mail an unseren Server. Dieser Code funktionierte in iOS6 einwandfrei.Speicherwarnung UIImagepickerController IOS 7

Wenn ich Bilder mache, ist mein Speicher Haufenwachstum mit jeder Bildschirmaufnahme und ich bekomme "Received Memory Warning" und schließlich - Beendet wegen Speicherdruck. -

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


} 

wahrscheinlich ist eine Speicherverwaltung. Ich werde Ihre Hilfe zu schätzen wissen

+0

Führen Sie den statischen Analysator aus, um festzustellen, ob Warnungen vorhanden sind. Dann starten Sie die App in Instruments und suchen Sie nach Lecks und behalten Sie Zyklen. – rmaddy

Antwort

7

Sie sind auf dem richtigen Weg mit Ihrer fixRotation Methode. Sie sollten jedoch auch Größe ändern das Bild. Ansonsten wird das Bild sehr groß, ~ 30 MB (abhängig vom Gerät).

Zur Kasse gehen this blog post wie Sie die Bilder richtig skalieren. Insbesondere werden die UIImage Kategorie Dateien, die Sie wollen, sind diese:

UIImage+Resize.h

UIImage+Resize.m

Es ist auch eine gute Idee, diese auf einem Hintergrund-Thread zu tun. So etwas wie dieser

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

Ich habe die Größe geändert, die Speichererweiterung wurde reduziert, aber es wird immer etwas langsamer, bis meine App abstürzt, irgendwie muss ich den Speicher leeren –

+0

Zuerst habe ich ein neues Projekt mit iOS7 mit den gleichen Klassen und Methoden und schließlich angegeben Ich habe die Größe der Bilder auf 640 x 480 und 480 x 640 geändert und dann habe ich die fixRotation-Methode angewendet, mein Speicher erhöht sich einmal, bei anderen Fotos jedoch nicht. –

+0

@cesartrujillocetina Können Sie Ihren endgültigen Arbeitscode anzeigen? Ich habe das gleiche Problem. – Danpe

4

UIImageWriteToSavedPhotosAlbum Methode Gebrauch 30M + Speicher auf iOS7.It nicht über Ihre Größe ändern oder fixrotation Methode.

+0

ich habe das selbe problem und skaliere das bild dösen nicht ... – Ladessa

+0

habe ich auch das selbe problem .. ist irgendjemand eine lösung? – Sabareesh

+0

Ja Mann, jedes Mal, wenn ich anrufe UIImageWriteToSavedPhotosAlbum meine App erhalten eine Speicherwarnung! Und natürlich abstürzen! –

1

ich dieses Problem behoben haben von JRG-Entwickler-s Antwort hier oben mit wenig Änderungen: I`m Kategorien mit Ausrichtung von Bild zu fixieren Ans es Verkleinerung vor präsentiert und wenn Sie fertig sind, nenne ich Schwaches Selbst

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

Code der Skalierung wurde aus dem Netz genommen: diese skaliert und fixiertes Bild auf meinem 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]; 
    } 
} 

und unteren zuweisen

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

und Code zum Ändern (Fixierung) Bildorientierung auch aus dem Netz genommen wurde:

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

bitte, don-t in minusing grausam sein, wenn etwas für jetzt Dummy) Im junior sieht)

Für die Antwort unten - das ist, warum Sie besser ein Bild verkleinern würden - weniger Speicher in Anspruch nehmen, aber nicht einfach das große 4MB Bild auf Disc speichern. Am Anfang hatte ich auch Gedächtnisprobleme - es wurde 30 Mb pro Sigle Foto gegessen - und ich musste 2 Fotos eins nach dem anderen machen ... jetzt funktioniert es gut und glatt. Fix Ausrichtung ist optional, aber ich würde sowieso empfehlen, verkleinern Sie das Foto verkleinern Sie es zu verkleinern.

Verwandte Themen