4

i'm trying to figure out this problem but failed after doing every thing i found on OS or google. Problem is that when i convert UIImage to NSData using UIImageJPEGRepresentation or UIImagePNGRepresentation it increases the memory size to 30Mb (believe me or not).
Here is my code

myImage= image;
LoginSinglton*loginObj = [LoginSinglton sharedInstance];
NSError *error;
NSData *pngData = UIImageJPEGRepresentation(image, scaleValue); //scaleVale is 1.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory

self.imageCurrentDateAndTime =[self getTimeAndDate];
 self.filePathAndDirectory = [documentsPath stringByAppendingPathComponent:@"Photos Dir"];

NSLog(@"Documents path %@",self.filePathAndDirectory);
if (![[NSFileManager defaultManager] createDirectoryAtPath:self.filePathAndDirectory
                               withIntermediateDirectories:NO
                                                attributes:nil
                                                     error:&error])
{
    NSLog(@"Create directory error: %@", error);
}
self.imageName= [NSString stringWithFormat:@"photo-%@-%@.jpg",loginObj.userWebID,self.imageCurrentDateAndTime];
 NSString *filePath = [self.filePathAndDirectory stringByAppendingPathComponent:self.imageName];

[pngData writeToFile:filePath atomically:YES]; //Write the file
[self writeImageThumbnailToFolder:image];
[self writeImageHomeViewThumbnailToFolder:image];  

I have tried following solution as well UIImageJPEGRepresentation - memory release issue
1- Used @autoreleasepool
2- done pngData = nil;
but still facing that memory issue.

EDIT I think i'm not able to convey my problem. It's ok if UIImageJPEGRepresentation taking huge memory,but memory should back to it's earlier position after saving that image. Hope this will help you in detail.

Community
  • 1
  • 1
iEngineer
  • 1,319
  • 1
  • 11
  • 27
  • 1
    What's the resolution of your picture ? Let me guess... 8 MegaPixels, that is 3264 x 2448, or 3264 x 2448 x 4 bytes, around 30 Mo per bitmap loaded into memory... Maybe that's your problem, if scaling down compression isn't enough, resize ? – Vinzzz Nov 27 '13 at 14:27
  • of course you are going to end up with a huge amount of data. You are taking a compressed image and decompressing it to its pure data representation, which will be huge. – MZimmerman6 Nov 27 '13 at 14:30
  • @Vinzzz I'm not sure about size but resolution is near to what you mentioned because i'm using 'AVCaptureSessionPresetPhoto' – iEngineer Nov 27 '13 at 14:32
  • @MZimmerman6 so what i should do now ? please guide me on this. – iEngineer Nov 27 '13 at 14:33
  • Just to be sure : when you're saying "it increases the memory size", you're talking about the size of final compressed file, or you're talking about the application live memory ? The latter is expected behavior, as UIImage bitmap must be loaded into memory to create JPEG, and with your AVCaptureSessionPreset, your bitmap is around 30 Mo, hence the memory pressure when saving full-size JPEGs – Vinzzz Nov 27 '13 at 14:41
  • I suggest you either use a smaller image or you use the suggestions that other people are making, reducing the quality factor if you truly do need that large of an image. I highly doubt that though because this is all being done on iOS. There are no iOS devices that have that high of a resolution – MZimmerman6 Nov 27 '13 at 14:42
  • @Vinzzz Yes you are right, I'm talking about application live memory, and it never goes down. Please help me on this. – iEngineer Nov 27 '13 at 14:47
  • 1
    Have your tried running 'Analyze' build in XCode ? Because if memory never goes down, it might be : 1/because your forgot to release some data (like CoreGraphics objects) 2/ by design : if you hold some pointer to a UIImage. In case 1/, "Analyze" should quickly warn you. Else, provide more code – Vinzzz Nov 27 '13 at 15:16
  • Also, if you just need to record JPEG data from Camera, why don't you use `AVCaptureStillImageOutput jpegStillImageNSDataRepresentation` ? – Vinzzz Nov 27 '13 at 15:17
  • What is the problem? Of course it will take 30MB to represent the image, that is what the memory is there for. – zaph Nov 27 '13 at 15:35
  • possible duplicate of [What's the easiest way to resize/optimize an image size with the iPhone SDK?](http://stackoverflow.com/questions/612131/whats-the-easiest-way-to-resize-optimize-an-image-size-with-the-iphone-sdk) – Rajesh Loganathan Nov 27 '13 at 15:49
  • @SVM-RAJESH, i do not want to resize the image, Please read the question before down voting it. – iEngineer Nov 28 '13 at 06:03
  • @iEngineer How can you tell am down voted yours ???? – Rajesh Loganathan Nov 28 '13 at 06:06
  • were you able to fix the issue? I'm having the same issue – imObjCSwifting Jan 22 '15 at 18:25

3 Answers3

8

Use a scaleValue of less than 1. Even 0.9 will massively reduce the memory footprint with minimal quality loss.

Guy Kogus
  • 7,251
  • 1
  • 27
  • 32
0

Try this:

UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

If not got solution for your expectation, no need to worry try this too:

UIImage *small = [UIImage imageWithCGImage:original.CGImage scale:0.25 orientation:original.imageOrientation];

Get sample app form here for editing image or scale: http://mattgemmell.com/2010/07/05/mgimageutilities/

Rajesh Loganathan
  • 11,129
  • 4
  • 78
  • 90
0

To resize using minimum memory try Using CoreGraphics

SO answer by @Mina Nabil, see full answer for more details

#import <ImageIO/ImageIO.h>
-(UIImage*) resizedImageToRect:(CGRect) thumbRect {
    CGImageRef          imageRef = [inImage CGImage];
    CGImageAlphaInfo    alphaInfo = CGImageGetAlphaInfo(imageRef);
    if (alphaInfo == kCGImageAlphaNone)
        alphaInfo = kCGImageAlphaNoneSkipLast;

    // Build a bitmap context that's the size of the thumbRect
    CGContextRef bitmap = CGBitmapContextCreate(
        NULL,
        thumbRect.size.width,       // width
        thumbRect.size.height,      // height
        CGImageGetBitsPerComponent(imageRef),   // really needs to always be 8
        4 * thumbRect.size.width,   // rowbytes
        CGImageGetColorSpace(imageRef),
        alphaInfo
        );

    // Draw into the context, this scales the image
    CGContextDrawImage(bitmap, thumbRect, imageRef);

    // Get an image from the context and a UIImage
    CGImageRef  ref = CGBitmapContextCreateImage(bitmap);
    UIImage*    result = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap);   // ok if NULL
    CGImageRelease(ref);

    return result;
}
Community
  • 1
  • 1
zaph
  • 111,848
  • 21
  • 189
  • 228