Skip to content

Instantly share code, notes, and snippets.

@katopz
Created April 4, 2014 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save katopz/9978509 to your computer and use it in GitHub Desktop.
Save katopz/9978509 to your computer and use it in GitHub Desktop.
Using 16 bits instead of 32 bits cuts memory usage in half : http://www.dwellable.com/blog/Tech-iOS-Image-Tricks
//
// gModel and friends
//
// iphone
// 1: 412mhz 128mb iPhone1,1
// 3g: 412mhz 128mb iPhone1,2
// 3gs: 600mhz 256mb iPhone2,1
// 4: 800mhz 512mb iPhone3,1-3
// 4s: 2x1ghz 512mb iPhone4,1
//
// ipad
// 1: 1ghz 256mb iPad1,1-2
// 2: 2x1ghz 512mb iPad2,1-2
// 3: 2x1ghz 1gb iPad3
//
// ipod
// 1: 412mhz 128mb iPod1,1
// 2: 533mhz 128mb iPod2,1
// 3: 600mhz 256mb iPod3,1
// 4: 800mhz 256mb iPod4,1
//
struct utsname u;
uname(&u);
gModel = [NSString stringWithCString:u.machine encoding:NSASCIIStringEncoding];
// < 600mhz
gIsLowCPU = [gModel matches:[NSRegularExpression re:@"^(iPhone1|iPod[12])"]];
// old iphones/ipod/ipads
gIsLowRam = [gModel matches:[NSRegularExpression re:@"^(iPhone1|iPod[12]|iPad1)"]];
//
// For anybody trying to copy 'n paste:
//
@implementation NSRegularExpression (Dwellable)
+ (NSRegularExpression *)re:(NSString *)s
{
return[NSRegularExpression regularExpressionWithPattern:s options:0 error:nil];
}
- (BOOL)matches:(NSString *)s
{
return [self numberOfMatchesInString:s options:0 range:NSMakeRange(0, s.length)];
}
@end
@implementation NSString (Dwellable)
- (BOOL)matches:(NSRegularExpression *)re
{
return [re matches:self];
}
@end
@implementation UIImage (Dwellable)
- (UIImage *)crop:(CGRect)rect
{
return [self copyFromRect:rect toSize:rect.size];
}
- (UIImage *)copyToSize:(CGSize)dstSize
{
return [self copyFromRect:CGRectMake(0, 0, self.size.width, self.size.height)
toSize:dstSize];
}
- (UIImage *)copyFromRect:(CGRect)srcRect toSize:(CGSize)dstSize
{
//
// apply scale if necessary
//
int scale = self.scale;
if (scale > 1) {
srcRect = CGRectMake(srcRect.origin.x * scale, srcRect.origin.y * scale,
srcRect.size.width * scale, srcRect.size.height * scale);
dstSize = CGSizeMake(dstSize.width * scale, dstSize.height * scale);
}
//
// create the context
//
int bpc = 8;
CGBitmapInfo bmi = kCGImageAlphaPremultipliedFirst;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (gIsLowRam) {
// 16bit if we don't have an alpha channel (this saves a ton of memory)
CGImageAlphaInfo alpha = CGImageGetAlphaInfo(self.CGImage);
if (alpha == kCGImageAlphaNone || alpha == kCGImageAlphaNoneSkipLast ||
alpha == kCGImageAlphaNoneSkipFirst) {
bpc = 5;
bmi = kCGImageAlphaNoneSkipFirst;
}
}
CGContextRef context = CGBitmapContextCreate(NULL, dstSize.width, dstSize.height,
bpc, 0, colorSpace, bmi);
CGColorSpaceRelease(colorSpace);
//
// interpolation quality set to high on everything but old iphones
//
CGInterpolationQuality quality = kCGInterpolationHigh;
if (gIsLowCPU) {
quality = kCGInterpolationDefault;
}
CGContextSetInterpolationQuality(context, quality);
//
// choose srcImage
//
CGImageRef srcImage;
if (!CGRectEqualToRect(srcRect, CGRectMake(0, 0, self.size.width * scale,
self.size.height * scale))) {
srcImage = CGImageCreateWithImageInRect(self.CGImage, srcRect);
} else {
srcImage = CGImageRetain(self.CGImage);
}
//
// copy
//
CGContextDrawImage(context, CGRectMake(0, 0, dstSize.width, dstSize.height),
srcImage);
CGImageRelease(srcImage);
CGImageRef dst = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *result = [UIImage imageWithCGImage:dst scale:scale
orientation:UIImageOrientationUp];
CGImageRelease(dst);
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment