CTUIImage+Extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CTUIImage+Extensions.h | |
// MineSweeper | |
// | |
// Created by Chad Weider on 3/29/12. | |
// Copyright (c) 2012 Chad Weider. All rights reserved. | |
// | |
#import <UIKit/UIKit.h> | |
@interface UIImage (CTUIImageExtensions) | |
+ (UIImage *)ct_imageWithPDFNamed:(NSString *)name size:(CGSize)size; | |
- (UIImage *)ct_imageWithShadowOffset:(CGSize)offset blur:(CGFloat)blur color:(UIColor *)color; | |
- (UIImage *)ct_imageWithOverlayColor:(UIColor *)color; | |
- (UIImage *)ct_imageWithInnerShadowOffset:(CGSize)offset color:(UIColor *)color; | |
@end | |
// | |
// CTUIImage+Extensions.m | |
// MineSweeper | |
// | |
// Created by Chad Weider on 3/29/12. | |
// Copyright (c) 2012 Chad Weider. All rights reserved. | |
// | |
#import "CTUIImage+Extensions.h" | |
@implementation UIImage (CTUIImageExtensions) | |
+ (UIImage *)ct_imageWithPDFNamed:(NSString *)name size:(CGSize)size | |
{ | |
CGFloat scale = 1; | |
CGColorSpaceRef colorspace = NULL; | |
CGContextRef layerContext = NULL; | |
void *layerBytes = NULL; | |
CGPDFDocumentRef iconDocument = NULL; | |
CGImageRef cg_image = NULL; | |
UIImage *image = nil; | |
if ([UIScreen instancesRespondToSelector:@selector(scale)]) | |
{ | |
scale = [[UIScreen mainScreen] scale]; | |
} | |
if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) | |
{ | |
size = CGSizeMake(size.width * scale, size.height * scale); | |
} | |
else | |
{ | |
scale = 1; | |
} | |
/* Setup */ | |
colorspace = CGColorSpaceCreateDeviceRGB(); | |
CGRect layerRect = CGRectMake(0, 0, size.width, size.height); | |
layerBytes = calloc(size.width * size.height, 4); | |
if (!layerBytes) | |
goto END_RENDER; | |
layerContext = CGBitmapContextCreate( | |
layerBytes, | |
size.width, | |
size.height, | |
8, | |
4 * size.width, | |
colorspace, | |
kCGImageAlphaPremultipliedLast); | |
if (!layerContext) | |
goto END_RENDER; | |
CFStringRef iconPath = (CFStringRef)[[NSBundle mainBundle] pathForResource:name ofType:@"pdf"]; | |
if (!iconPath) | |
goto END_RENDER; | |
CFURLRef iconURL = CFURLCreateWithFileSystemPath(NULL, iconPath, kCFURLPOSIXPathStyle, false); | |
iconDocument = CGPDFDocumentCreateWithURL(iconURL); | |
CFRelease(iconURL); | |
if (!iconDocument) | |
goto END_RENDER; | |
CGPDFPageRef iconPage = CGPDFDocumentGetPage(iconDocument, 1); | |
/* Draw */ | |
CGRect iconRect = CGPDFPageGetBoxRect(iconPage, kCGPDFCropBox); | |
CGAffineTransform iconTransform = CGPDFPageGetDrawingTransform(iconPage, kCGPDFCropBox, iconRect, 0, true); | |
CGFloat scaleFactor = MIN(layerRect.size.width/iconRect.size.width, layerRect.size.height/iconRect.size.width); | |
iconTransform = CGAffineTransformTranslate(iconTransform, CGRectGetWidth(layerRect)/2., CGRectGetHeight(layerRect)/2.); | |
iconTransform = CGAffineTransformScale(iconTransform, scaleFactor, scaleFactor); | |
iconTransform = CGAffineTransformTranslate(iconTransform, -CGRectGetMinX(iconRect)-CGRectGetWidth(iconRect)/2., -CGRectGetMinY(iconRect)-CGRectGetHeight(iconRect)/2.); | |
CGContextConcatCTM(layerContext, iconTransform); | |
CGContextDrawPDFPage(layerContext, iconPage); | |
/* Render */ | |
cg_image = CGBitmapContextCreateImage(layerContext); | |
if (!cg_image) | |
goto END_RENDER; | |
if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) | |
{ | |
image = [UIImage imageWithCGImage:cg_image scale:scale orientation:UIImageOrientationUp]; | |
} | |
else | |
{ | |
image = [UIImage imageWithCGImage:cg_image]; | |
} | |
END_RENDER: | |
if (cg_image != NULL) | |
CGImageRelease(cg_image); | |
if (iconDocument != NULL) | |
CGPDFDocumentRelease(iconDocument); | |
if (layerContext != NULL) | |
CGContextRelease(layerContext); | |
if (layerBytes != NULL) | |
free(layerBytes); | |
if (colorspace != NULL) | |
CGColorSpaceRelease(colorspace); | |
return image; | |
} | |
- (UIImage *)ct_imageWithShadowOffset:(CGSize)offset blur:(CGFloat)blur color:(UIColor *)color | |
{ | |
CGColorSpaceRef colorspace = NULL; | |
CGContextRef layerContext = NULL; | |
void *layerBytes = NULL; | |
CGImageRef cg_image = NULL; | |
UIImage *image = nil; | |
CGFloat scale = [self respondsToSelector:@selector(scale)] ? [self scale] : 1; | |
CGSize size = [self size]; | |
if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) | |
{ | |
size = CGSizeMake(size.width * scale, size.height * scale); | |
offset = CGSizeMake(offset.width * scale, offset.height * scale); | |
blur = blur * scale; | |
} | |
else | |
{ | |
scale = 1; | |
} | |
blur = MAX(blur, 0); | |
offset = CGSizeMake(offset.width, -offset.height); | |
/* Setup */ | |
colorspace = CGColorSpaceCreateDeviceRGB(); | |
CGRect layerRect = CGRectMake(ceilf(blur+fabs(offset.width)), ceilf(blur+fabs(offset.height)), size.width, size.height); | |
size = CGSizeMake(size.width+ceilf(blur+fabsf(offset.width))*2, size.height+ceilf(+blur+fabsf(offset.height))*2); | |
layerBytes = calloc(size.width * size.height, 4); | |
if (!layerBytes) | |
goto END_RENDER; | |
layerContext = CGBitmapContextCreate( | |
layerBytes, | |
size.width, | |
size.height, | |
8, | |
4 * size.width, | |
colorspace, | |
kCGImageAlphaPremultipliedLast); | |
if (!layerContext) | |
goto END_RENDER; | |
/* Draw */ | |
CGContextSetShadowWithColor(layerContext, offset, blur, [color CGColor]); | |
CGContextBeginTransparencyLayer(layerContext, NULL); | |
CGContextDrawImage(layerContext, layerRect, [self CGImage]); | |
CGContextEndTransparencyLayer(layerContext); | |
/* Render */ | |
cg_image = CGBitmapContextCreateImage(layerContext); | |
if (!cg_image) | |
goto END_RENDER; | |
if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) | |
{ | |
image = [UIImage imageWithCGImage:cg_image scale:scale orientation:UIImageOrientationUp]; | |
} | |
else | |
{ | |
image = [UIImage imageWithCGImage:cg_image]; | |
} | |
END_RENDER: | |
if (colorspace != NULL) | |
CGColorSpaceRelease(colorspace); | |
if (layerContext != NULL) | |
CGContextRelease(layerContext); | |
if (cg_image != NULL) | |
CGImageRelease(cg_image); | |
if (layerBytes != NULL) | |
free(layerBytes); | |
return image; | |
} | |
- (UIImage *)ct_imageWithOverlayColor:(UIColor *)color | |
{ | |
CGColorSpaceRef colorspace = NULL; | |
CGContextRef layerContext = NULL; | |
void *layerBytes = NULL; | |
CGImageRef cg_image = NULL; | |
UIImage *image = nil; | |
CGFloat scale = [self respondsToSelector:@selector(scale)] ? [self scale] : 1; | |
CGSize size = [self size]; | |
if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) | |
{ | |
size = CGSizeMake(size.width * scale, size.height * scale); | |
} | |
else | |
{ | |
scale = 1; | |
} | |
/* Setup */ | |
colorspace = CGColorSpaceCreateDeviceRGB(); | |
CGRect layerRect = CGRectMake(0, 0, size.width, size.height); | |
layerBytes = calloc(size.width * size.height, 4); | |
if (!layerBytes) | |
goto END_RENDER; | |
layerContext = CGBitmapContextCreate( | |
layerBytes, | |
size.width, | |
size.height, | |
8, | |
4 * size.width, | |
colorspace, | |
kCGImageAlphaPremultipliedLast); | |
if (!layerContext) | |
goto END_RENDER; | |
/* Draw */ | |
CGContextDrawImage(layerContext, layerRect, [self CGImage]); | |
CGContextSetBlendMode(layerContext, kCGBlendModeSourceIn); | |
CGContextSetFillColorWithColor(layerContext, [color CGColor]); | |
CGContextFillRect(layerContext, layerRect); | |
/* Render */ | |
cg_image = CGBitmapContextCreateImage(layerContext); | |
if (!cg_image) | |
goto END_RENDER; | |
if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) | |
{ | |
image = [UIImage imageWithCGImage:cg_image scale:scale orientation:UIImageOrientationUp]; | |
} | |
else | |
{ | |
image = [UIImage imageWithCGImage:cg_image]; | |
} | |
END_RENDER: | |
if (colorspace != NULL) | |
CGColorSpaceRelease(colorspace); | |
if (layerContext != NULL) | |
CGContextRelease(layerContext); | |
if (cg_image != NULL) | |
CGImageRelease(cg_image); | |
if (layerBytes != NULL) | |
free(layerBytes); | |
return image; | |
} | |
- (UIImage *)ct_imageWithInnerShadowOffset:(CGSize)offset color:(UIColor *)color | |
{ | |
CGColorSpaceRef colorspace = NULL; | |
CGContextRef layerContext = NULL; | |
void *layerBytes = NULL; | |
CGImageRef cg_image = NULL; | |
UIImage *image = nil; | |
CGFloat scale = [self respondsToSelector:@selector(scale)] ? [self scale] : 1; | |
CGSize size = [self size]; | |
if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) | |
{ | |
size = CGSizeMake(size.width * scale, size.height * scale); | |
offset = CGSizeMake(offset.width * scale, offset.height * scale); | |
} | |
else | |
{ | |
scale = 1; | |
} | |
offset = CGSizeMake(offset.width, -offset.height); | |
/* Setup */ | |
colorspace = CGColorSpaceCreateDeviceRGB(); | |
CGRect layerRect = CGRectMake(0, 0, size.width, size.height); | |
layerBytes = calloc(size.width * size.height, 4); | |
if (!layerBytes) | |
goto END_RENDER; | |
layerContext = CGBitmapContextCreate( | |
layerBytes, | |
size.width, | |
size.height, | |
8, | |
4 * size.width, | |
colorspace, | |
kCGImageAlphaPremultipliedLast); | |
if (!layerContext) | |
goto END_RENDER; | |
/* Draw */ | |
CGContextDrawImage(layerContext, layerRect, [self CGImage]); | |
CGLayerRef shadowLayer = CGLayerCreateWithContext(layerContext, layerRect.size, NULL); | |
CGContextRef shadowContext = CGLayerGetContext(shadowLayer); | |
CGContextDrawImage(shadowContext, CGRectOffset(layerRect, offset.width, offset.height), [self CGImage]); | |
CGContextSetBlendMode(shadowContext, kCGBlendModeSourceOut); | |
CGContextSetFillColorWithColor(shadowContext, [color CGColor]); | |
CGContextFillRect(shadowContext, layerRect); | |
CGContextSetBlendMode(layerContext, kCGBlendModeSourceAtop); | |
CGContextDrawLayerInRect(layerContext, layerRect, shadowLayer); | |
CGLayerRelease(shadowLayer); | |
/* Render */ | |
cg_image = CGBitmapContextCreateImage(layerContext); | |
if (!cg_image) | |
goto END_RENDER; | |
if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) | |
{ | |
image = [UIImage imageWithCGImage:cg_image scale:scale orientation:UIImageOrientationUp]; | |
} | |
else | |
{ | |
image = [UIImage imageWithCGImage:cg_image]; | |
} | |
END_RENDER: | |
if (colorspace != NULL) | |
CGColorSpaceRelease(colorspace); | |
if (layerContext != NULL) | |
CGContextRelease(layerContext); | |
if (cg_image != NULL) | |
CGImageRelease(cg_image); | |
if (layerBytes != NULL) | |
free(layerBytes); | |
return image; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment