3

I'm suffered from resizing image from original resolution image, which is about 8MP, my output resolution is about 2MP. Sometimes, it show memory warning for iPhone4S device, and I did some release in memorywarning, but it sometimes make my program crash for alassetlibrary usage problem. Here's my question, I want to prevent from memory warning during my resizing fullReoslutionImage.

I tried many method for resizing image. my current method is about 44MB increase for peak memory usage. it seems too large...for overall system, it will have a peak for 57 MB..... I tried CGImageSourceCreateThumbnailAtIndex, but it introduce more memory increase than my current method.

Here's my solution, but it still introduce sometimes memorywarning. Do you have other methods? Could you help me? some ideas, 1. Other iOS API? 2. native library for on-the-fly resize for JPEG decoder? 3. YUV422 resizer instead of RGBA. 4. ..... I have no idea...

UIImage *image=[self oriImageThumbnailAtIndex:asset];
        CGInterpolationQuality interpolationQuality=kCGInterpolationMedium;            
        CGSize newSize=[self sizeDown:image.size];            
        image2 =makeResizedImageRotate(image, newSize, interpolationQuality,[defaultRep orientation]);


-(UIImage *) oriImageThumbnailAtIndex:(ALAsset *)asset
{
int times=0;
ALAssetRepresentation* assetRepresentation=asset.defaultRepresentation;
long long imageDataSize = [assetRepresentation size];    
uint8_t* imageDataBytes = (uint8_t*) malloc(imageDataSize);
[assetRepresentation getBytes:imageDataBytes fromOffset:0 length:imageDataSize error:nil];
NSData *data = [NSData dataWithBytesNoCopy:imageDataBytes length:imageDataSize freeWhenDone:YES];
UIImage *image2=nil;  
CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef) data, NULL);        
CGImageRef thumbnail;
if (src)
{
    float _maxSize=RESIZE_IMAGE_BIG_SIDE;
    thumbnail = CGImageSourceCreateImageAtIndex(src, 0, NULL); // Create scaled image
    image2 = [UIImage imageWithCGImage:thumbnail];        
    CGImageRelease(thumbnail);        
}else{
    NSLog(@"resizeImage:(ALAsset *)asset error!!!");        
}

return image2;
}

UIImage* makeResizedImageRotate(UIImage *inimage,CGSize newSize,CGInterpolationQuality interpolationQuality,UIImageOrientation orient) {
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGImageRef imageRef = inimage.CGImage;

// Compute the bytes per row of the new image
size_t bytesPerRow = CGImageGetBitsPerPixel(imageRef) / CGImageGetBitsPerComponent(imageRef) * newRect.size.width;
bytesPerRow = (bytesPerRow + 15) & ~15;  // Make it 16-byte aligned
  CGBitmapInfo cgbmpinfo=CGImageGetBitmapInfo(imageRef);
CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                            newRect.size.width,
                                            newRect.size.height,
                                            CGImageGetBitsPerComponent(imageRef),
                                            bytesPerRow,
                                            CGImageGetColorSpace(imageRef),
                                            cgbmpinfo);
if(bitmap!=nil)
    CGContextSetInterpolationQuality(bitmap, interpolationQuality);
else
    NSLog(@"bitmap==nil");


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

// Get the resized image from the context and a UIImage
CGImageRef resizedImageRef = CGBitmapContextCreateImage(bitmap);
UIImage *resizedImage = [UIImage imageWithCGImage:resizedImageRef];
CGContextRelease(bitmap);
CGImageRelease(resizedImageRef);
resizedImage=rotateImage( resizedImage, orient);
// Clean up

// [resizedImage autorelease]; will introduce BAD_ADDRESS
return resizedImage;

}

Bruce Tsai
  • 1,440
  • 2
  • 12
  • 18
  • ...duplicate question: http://stackoverflow.com/questions/13251262/what-is-the-most-memory-efficient-way-of-downscaling-images-on-ios – kineticfocus Nov 11 '12 at 01:54
  • I just tried libjpeg-turbo, it's fast enough, and it can support resize during decoding JPEG. However, it seems only support 1/2, 1/4, 1/8 downsample ratio, what I need is about >=0.55(from 3264 to 1800), so it can't achieve my target....still finding solution....Is any JPEG decoder can support rational ratio downsampling? – Bruce Tsai Nov 11 '12 at 11:57
  • 1
    http://libjpeg-turbo.sourceforge.net/ljt.nightly/ The author told me this binary version for libjpeg-turbo can support more scaling factor . It can support 16 scaling factors. Maybe someone will need it. – Bruce Tsai Nov 13 '12 at 09:04
  • possible duplicate of [The simplest way to resize an UIImage?](http://stackoverflow.com/questions/2658738/the-simplest-way-to-resize-an-uiimage) – sanmai Sep 17 '13 at 03:11

2 Answers2

1

I found it was reduced much when I use 3rd party JPEG decode library(libjpeg-turbo) to decode&resize it under 2048x2048 UIImage.(even the total memory is not reduced much.) So the memory wanring happen so often may be caused by creating UIImage larger than 2Kx2K. Hope this helps.

Bruce Tsai
  • 1,440
  • 2
  • 12
  • 18
  • This will help for this issue and optimisation : https://stackoverflow.com/questions/49305438/how-to-get-thumb-image-from-photolibrary-image – Nilesh Kikani Jun 28 '18 at 11:12
0

I am using the below code

-(UIImage*) generateThumbnailFromImage:(UIImage*)mainImage
{
    UIImage * thumbnail;

    CGSize destinationSize = CGSizeMake(thumbnail image width,thumbnail image height);

    UIGraphicsBeginImageContext(destinationSize);
    [mainImage drawInRect:CGRectMake(0,0,destinationSize.width, destinationSize.height)];
    thumbnail = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return thumbnail;
}

i never faced memory warning with this try how it works with your code.

codelark
  • 12,254
  • 1
  • 45
  • 49
spider1983
  • 1,098
  • 1
  • 7
  • 14
  • Thank you very much. I tried it , but it increases about 58MB, and 71MB for peak. so, it seems not decrease memory usage. my another question is why I easily get memory warning for ipad2 and iphone4s, but seldome for iphone4. Is any things for me to check. I wonder maybe I did something wrong. Here's my code for trying your way. UIImage *image= [UIImage imageWithCGImage:defaultRep.fullResolutionImage]; image2=[self generateThumbnailFromImage:image andOsize:newSize ]; – Bruce Tsai Nov 10 '12 at 14:06
  • I measure my memory usage by instrument, and it show about 57MB for the peak. I thought it's root cause for memory warning, or other causes ? dirty memory or leaks related to it? I don' know what's the abnormal case for dirty memory... My app is multi-select images to resize and upload to server. multi-select is implemented by ALAssetlibrary. I will resize image when user tap the thumbnail, then it may sometimes receive memory warning... I'm frustrated in this problem for one month...Any helps are appreciated. – Bruce Tsai Nov 10 '12 at 14:34
  • Its not necessary that the warning in your case is coming from creating the thumbnails...it may happen that some memory are being assigned by other objects and all together making the warning to occur. – spider1983 Nov 12 '12 at 06:22
  • Sorry, I don't understand your meaning. How can I prevent from memory warning ? In fact, I only create the thumnail view for what user can see, maybe 28 thumbnail view. However, I really feel this is related to thumbnail view, becausue I used to use image picker to load 8MP image, and it never show memory warning. But in my current project, I use assetlibrary, and it seems more easily to get memory warning. So, you comments is valuable. BTW, I got memory warning after resizing image. Please tell me more details. Thank you. – Bruce Tsai Nov 13 '12 at 08:59
  • i guess if you are getting memory warning in iPad2 and iPhone 4s frequently then you should check the assetlibrary you are using is that compatible for the ios on which you are checking, i can only guess waht might be happening on this amount of information. – spider1983 Nov 13 '12 at 16:05