I have a 1600x1600 1.2MB image which resized to 320x320 shrinks to 404KB. I need to go further and reduce the bytes size without reducing the image aspect size.
Curr
If you need compression and you don't mind losing image quality then save the file as a JPEG. To do this, you need to get an NSBitmapImageRep
from your image and then get a JPEG representation:
//yourImage is an NSImage object
NSBitmapImageRep* myBitmapImageRep;
if(useActualSize)
{
//this will produce an image the full size of the NSImage's backing bitmap, which may not be what you want
myBitmapImageRep = [NSBitmapImageRep imageRepWithData: [yourImage TIFFRepresentation]];
}
else
{
//this will get a bitmap from the image at 1 point == 1 pixel, which is probably what you want
NSSize imageSize = [yourImage size];
[yourImage lockFocus];
NSRect imageRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
myBitmapImageRep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:imageRect] autorelease];
[yourImage unlockFocus];
}
CGFloat imageCompression = 0.7; //between 0 and 1; 1 is maximum quality, 0 is maximum compression
// set up the options for creating a JPEG
NSDictionary* jpegOptions = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:imageCompression], NSImageCompressionFactor,
[NSNumber numberWithBool:NO], NSImageProgressive,
nil];
// get the JPEG encoded data
NSData* jpegData = [myBitmapImageRep representationUsingType:NSJPEGFileType properties:jpegOptions];
//write it to disk
[jpegData writeToFile:[NSHomeDirectory() stringByAppendingPathComponent:@"foo.jpg"] atomically:YES];
#import "UIImage+Compress.h"
#define MAX_IMAGEPIX 200.0 // max pix 200.0px
#define MAX_IMAGEDATA_LEN 50000.0 // max data length 5K
@implementation UIImage (Compress)
- (UIImage *)compressedImage {
CGSize imageSize = self.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
if (width <= MAX_IMAGEPIX && height <= MAX_IMAGEPIX) {
// no need to compress.
return self;
}
if (width == 0 || height == 0) {
// void zero exception
return self;
}
UIImage *newImage = nil;
CGFloat widthFactor = MAX_IMAGEPIX / width;
CGFloat heightFactor = MAX_IMAGEPIX / height;
CGFloat scaleFactor = 0.0;
if (widthFactor > heightFactor)
scaleFactor = heightFactor; // scale to fit height
else
scaleFactor = widthFactor; // scale to fit width
CGFloat scaledWidth = width * scaleFactor;
CGFloat scaledHeight = height * scaleFactor;
CGSize targetSize = CGSizeMake(scaledWidth, scaledHeight);
UIGraphicsBeginImageContext(targetSize); // this will crop
CGRect thumbnailRect = CGRectZero;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[self drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
//pop the context to get back to the default
UIGraphicsEndImageContext();
return newImage;
}
- (NSData *)compressedData:(CGFloat)compressionQuality {
assert(compressionQuality <= 1.0 && compressionQuality >= 0);
return UIImageJPEGRepresentation(self, compressionQuality);
}
- (CGFloat)compressionQuality {
NSData *data = UIImageJPEGRepresentation(self, 1.0);
NSUInteger dataLength = [data length];
if(dataLength > MAX_IMAGEDATA_LEN) {
return 1.0 - MAX_IMAGEDATA_LEN / dataLength;
} else {
return 1.0;
}
}
- (NSData *)compressedData {
CGFloat quality = [self compressionQuality];
return [self compressedData:quality];
}
@end