├── Categories ├── UIImage+Blurring.h ├── UIImage+Blurring.m ├── UIImage+Enhancing.h ├── UIImage+Enhancing.m ├── UIImage+Filtering.h ├── UIImage+Filtering.m ├── UIImage+Masking.h ├── UIImage+Masking.m ├── UIImage+Reflection.h ├── UIImage+Reflection.m ├── UIImage+Resizing.h ├── UIImage+Resizing.m ├── UIImage+Rotating.h ├── UIImage+Rotating.m ├── UIImage+Saving.h ├── UIImage+Saving.m ├── UIScrollView+Screenshot.h ├── UIScrollView+Screenshot.m ├── UIView+Screenshot.h └── UIView+Screenshot.m ├── Classes ├── NYXProgressiveImageView.h └── NYXProgressiveImageView.m ├── Helper ├── NYXImagesHelper.h ├── NYXImagesHelper.m └── NYXImagesKit.h ├── LICENSE.txt ├── NYXImagesKit.podspec ├── NYXImagesKit.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── Nyxouf.xcuserdatad │ │ └── WorkspaceSettings.xcsettings └── xcuserdata │ └── Nyxouf.xcuserdatad │ ├── xcdebugger │ └── Breakpoints.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── Other Sources └── Prefix.pch └── readme.md /Categories/UIImage+Blurring.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Blurring.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 03/06/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | @interface UIImage (NYX_Blurring) 15 | 16 | -(UIImage*)gaussianBlurWithBias:(NSInteger)bias; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Categories/UIImage+Blurring.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Blurring.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 03/06/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Blurring.h" 12 | #import 13 | 14 | 15 | static int16_t __s_gaussianblur_kernel_5x5[25] = { 16 | 1, 4, 6, 4, 1, 17 | 4, 16, 24, 16, 4, 18 | 6, 24, 36, 24, 6, 19 | 4, 16, 24, 16, 4, 20 | 1, 4, 6, 4, 1 21 | }; 22 | 23 | 24 | @implementation UIImage (NYX_Blurring) 25 | 26 | -(UIImage*)gaussianBlurWithBias:(NSInteger)bias 27 | { 28 | /// Create an ARGB bitmap context 29 | const size_t width = (size_t)self.size.width; 30 | const size_t height = (size_t)self.size.height; 31 | const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel; 32 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow, NYXImageHasAlpha(self.CGImage)); 33 | if (!bmContext) 34 | return nil; 35 | 36 | /// Draw the image in the bitmap context 37 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 38 | 39 | /// Grab the image raw data 40 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 41 | if (!data) 42 | { 43 | CGContextRelease(bmContext); 44 | return nil; 45 | } 46 | 47 | const size_t n = sizeof(UInt8) * width * height * 4; 48 | void* outt = malloc(n); 49 | vImage_Buffer src = {data, height, width, bytesPerRow}; 50 | vImage_Buffer dest = {outt, height, width, bytesPerRow}; 51 | vImageConvolveWithBias_ARGB8888(&src, &dest, NULL, 0, 0, __s_gaussianblur_kernel_5x5, 5, 5, 256/*divisor*/, (int32_t)bias, NULL, kvImageCopyInPlace); 52 | memcpy(data, outt, n); 53 | free(outt); 54 | 55 | CGImageRef blurredImageRef = CGBitmapContextCreateImage(bmContext); 56 | UIImage* blurred = [UIImage imageWithCGImage:blurredImageRef]; 57 | 58 | /// Cleanup 59 | CGImageRelease(blurredImageRef); 60 | CGContextRelease(bmContext); 61 | 62 | return blurred; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Categories/UIImage+Enhancing.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Enhancing.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 03/12/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | @interface UIImage (NYX_Enhancing) 12 | 13 | -(UIImage*)autoEnhance; 14 | 15 | -(UIImage*)redEyeCorrection; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Categories/UIImage+Enhancing.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Enhancing.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 03/12/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Enhancing.h" 12 | #import 13 | 14 | 15 | @implementation UIImage (NYX_Enhancing) 16 | 17 | -(UIImage*)autoEnhance 18 | { 19 | /// No Core Image, return original image 20 | if (![CIImage class]) 21 | return self; 22 | 23 | CIImage* ciImage = [[CIImage alloc] initWithCGImage:self.CGImage]; 24 | 25 | NSArray* adjustments = [ciImage autoAdjustmentFiltersWithOptions:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:kCIImageAutoAdjustRedEye]]; 26 | 27 | for (CIFilter* filter in adjustments) 28 | { 29 | [filter setValue:ciImage forKey:kCIInputImageKey]; 30 | ciImage = filter.outputImage; 31 | } 32 | 33 | CIContext* ctx = [CIContext contextWithOptions:nil]; 34 | CGImageRef cgImage = [ctx createCGImage:ciImage fromRect:[ciImage extent]]; 35 | UIImage* final = [UIImage imageWithCGImage:cgImage]; 36 | CGImageRelease(cgImage); 37 | return final; 38 | } 39 | 40 | -(UIImage*)redEyeCorrection 41 | { 42 | /// No Core Image, return original image 43 | if (![CIImage class]) 44 | return self; 45 | 46 | CIImage* ciImage = [[CIImage alloc] initWithCGImage:self.CGImage]; 47 | 48 | /// Get the filters and apply them to the image 49 | NSArray* filters = [ciImage autoAdjustmentFiltersWithOptions:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:kCIImageAutoAdjustEnhance]]; 50 | for (CIFilter* filter in filters) 51 | { 52 | [filter setValue:ciImage forKey:kCIInputImageKey]; 53 | ciImage = filter.outputImage; 54 | } 55 | 56 | /// Create the corrected image 57 | CIContext* ctx = [CIContext contextWithOptions:nil]; 58 | CGImageRef cgImage = [ctx createCGImage:ciImage fromRect:[ciImage extent]]; 59 | UIImage* final = [UIImage imageWithCGImage:cgImage]; 60 | CGImageRelease(cgImage); 61 | return final; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /Categories/UIImage+Filtering.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Filters.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | @interface UIImage (NYX_Filtering) 15 | 16 | -(UIImage*)brightenWithValue:(float)factor; 17 | 18 | -(UIImage*)contrastAdjustmentWithValue:(float)value; 19 | 20 | -(UIImage*)edgeDetectionWithBias:(NSInteger)bias; 21 | 22 | -(UIImage*)embossWithBias:(NSInteger)bias; 23 | 24 | -(UIImage*)gammaCorrectionWithValue:(float)value; 25 | 26 | -(UIImage*)grayscale; 27 | 28 | -(UIImage*)invert; 29 | 30 | -(UIImage*)opacity:(float)value; 31 | 32 | -(UIImage*)sepia; 33 | 34 | -(UIImage*)sharpenWithBias:(NSInteger)bias; 35 | 36 | -(UIImage*)unsharpenWithBias:(NSInteger)bias; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Categories/UIImage+Filtering.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Filters.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Filtering.h" 12 | #import 13 | #import 14 | 15 | 16 | /* Sepia values for manual filtering (< iOS 5) */ 17 | static float const __sepiaFactorRedRed = 0.393f; 18 | static float const __sepiaFactorRedGreen = 0.349f; 19 | static float const __sepiaFactorRedBlue = 0.272f; 20 | static float const __sepiaFactorGreenRed = 0.769f; 21 | static float const __sepiaFactorGreenGreen = 0.686f; 22 | static float const __sepiaFactorGreenBlue = 0.534f; 23 | static float const __sepiaFactorBlueRed = 0.189f; 24 | static float const __sepiaFactorBlueGreen = 0.168f; 25 | static float const __sepiaFactorBlueBlue = 0.131f; 26 | 27 | /* Negative multiplier to invert a number */ 28 | static float __negativeMultiplier = -1.0f; 29 | 30 | #pragma mark - Edge detection kernels 31 | /* vImage kernel */ 32 | /*static int16_t __s_edgedetect_kernel_3x3[9] = { 33 | -1, -1, -1, 34 | -1, 8, -1, 35 | -1, -1, -1 36 | };*/ 37 | /* vDSP kernel */ 38 | static float __f_edgedetect_kernel_3x3[9] = { 39 | -1.0f, -1.0f, -1.0f, 40 | -1.0f, 8.0f, -1.0f, 41 | -1.0f, -1.0f, -1.0f 42 | }; 43 | 44 | #pragma mark - Emboss kernels 45 | /* vImage kernel */ 46 | static int16_t __s_emboss_kernel_3x3[9] = { 47 | -2, 0, 0, 48 | 0, 1, 0, 49 | 0, 0, 2 50 | }; 51 | 52 | #pragma mark - Sharpen kernels 53 | /* vImage kernel */ 54 | static int16_t __s_sharpen_kernel_3x3[9] = { 55 | -1, -1, -1, 56 | -1, 9, -1, 57 | -1, -1, -1 58 | }; 59 | 60 | #pragma mark - Unsharpen kernels 61 | /* vImage kernel */ 62 | static int16_t __s_unsharpen_kernel_3x3[9] = { 63 | -1, -1, -1, 64 | -1, 17, -1, 65 | -1, -1, -1 66 | }; 67 | 68 | 69 | @implementation UIImage (NYX_Filtering) 70 | 71 | // Value should be in the range (-255, 255) 72 | -(UIImage*)brightenWithValue:(float)value 73 | { 74 | /// Create an ARGB bitmap context 75 | const size_t width = (size_t)self.size.width; 76 | const size_t height = (size_t)self.size.height; 77 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, width * kNyxNumberOfComponentsPerARBGPixel, NYXImageHasAlpha(self.CGImage)); 78 | if (!bmContext) 79 | return nil; 80 | 81 | /// Draw the image in the bitmap context 82 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 83 | 84 | /// Grab the image raw data 85 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 86 | if (!data) 87 | { 88 | CGContextRelease(bmContext); 89 | return nil; 90 | } 91 | 92 | const size_t pixelsCount = width * height; 93 | float* dataAsFloat = (float*)malloc(sizeof(float) * pixelsCount); 94 | float min = (float)kNyxMinPixelComponentValue, max = (float)kNyxMaxPixelComponentValue; 95 | 96 | /// Calculate red components 97 | vDSP_vfltu8(data + 1, 4, dataAsFloat, 1, pixelsCount); 98 | vDSP_vsadd(dataAsFloat, 1, &value, dataAsFloat, 1, pixelsCount); 99 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 100 | vDSP_vfixu8(dataAsFloat, 1, data + 1, 4, pixelsCount); 101 | 102 | /// Calculate green components 103 | vDSP_vfltu8(data + 2, 4, dataAsFloat, 1, pixelsCount); 104 | vDSP_vsadd(dataAsFloat, 1, &value, dataAsFloat, 1, pixelsCount); 105 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 106 | vDSP_vfixu8(dataAsFloat, 1, data + 2, 4, pixelsCount); 107 | 108 | /// Calculate blue components 109 | vDSP_vfltu8(data + 3, 4, dataAsFloat, 1, pixelsCount); 110 | vDSP_vsadd(dataAsFloat, 1, &value, dataAsFloat, 1, pixelsCount); 111 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 112 | vDSP_vfixu8(dataAsFloat, 1, data + 3, 4, pixelsCount); 113 | 114 | CGImageRef brightenedImageRef = CGBitmapContextCreateImage(bmContext); 115 | UIImage* brightened = [UIImage imageWithCGImage:brightenedImageRef scale:self.scale orientation:self.imageOrientation]; 116 | 117 | /// Cleanup 118 | CGImageRelease(brightenedImageRef); 119 | free(dataAsFloat); 120 | CGContextRelease(bmContext); 121 | 122 | return brightened; 123 | } 124 | 125 | /// (-255, 255) 126 | -(UIImage*)contrastAdjustmentWithValue:(float)value 127 | { 128 | /// Create an ARGB bitmap context 129 | const size_t width = (size_t)self.size.width; 130 | const size_t height = (size_t)self.size.height; 131 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, width * kNyxNumberOfComponentsPerARBGPixel, NYXImageHasAlpha(self.CGImage)); 132 | if (!bmContext) 133 | return nil; 134 | 135 | /// Draw the image in the bitmap context 136 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 137 | 138 | /// Grab the image raw data 139 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 140 | if (!data) 141 | { 142 | CGContextRelease(bmContext); 143 | return nil; 144 | } 145 | 146 | const size_t pixelsCount = width * height; 147 | float* dataAsFloat = (float*)malloc(sizeof(float) * pixelsCount); 148 | float min = (float)kNyxMinPixelComponentValue, max = (float)kNyxMaxPixelComponentValue; 149 | 150 | /// Contrast correction factor 151 | const float factor = (259.0f * (value + 255.0f)) / (255.0f * (259.0f - value)); 152 | 153 | float v1 = -128.0f, v2 = 128.0f; 154 | 155 | /// Calculate red components 156 | vDSP_vfltu8(data + 1, 4, dataAsFloat, 1, pixelsCount); 157 | vDSP_vsadd(dataAsFloat, 1, &v1, dataAsFloat, 1, pixelsCount); 158 | vDSP_vsmul(dataAsFloat, 1, &factor, dataAsFloat, 1, pixelsCount); 159 | vDSP_vsadd(dataAsFloat, 1, &v2, dataAsFloat, 1, pixelsCount); 160 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 161 | vDSP_vfixu8(dataAsFloat, 1, data + 1, 4, pixelsCount); 162 | 163 | /// Calculate green components 164 | vDSP_vfltu8(data + 2, 4, dataAsFloat, 1, pixelsCount); 165 | vDSP_vsadd(dataAsFloat, 1, &v1, dataAsFloat, 1, pixelsCount); 166 | vDSP_vsmul(dataAsFloat, 1, &factor, dataAsFloat, 1, pixelsCount); 167 | vDSP_vsadd(dataAsFloat, 1, &v2, dataAsFloat, 1, pixelsCount); 168 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 169 | vDSP_vfixu8(dataAsFloat, 1, data + 2, 4, pixelsCount); 170 | 171 | /// Calculate blue components 172 | vDSP_vfltu8(data + 3, 4, dataAsFloat, 1, pixelsCount); 173 | vDSP_vsadd(dataAsFloat, 1, &v1, dataAsFloat, 1, pixelsCount); 174 | vDSP_vsmul(dataAsFloat, 1, &factor, dataAsFloat, 1, pixelsCount); 175 | vDSP_vsadd(dataAsFloat, 1, &v2, dataAsFloat, 1, pixelsCount); 176 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 177 | vDSP_vfixu8(dataAsFloat, 1, data + 3, 4, pixelsCount); 178 | 179 | /// Create an image object from the context 180 | CGImageRef contrastedImageRef = CGBitmapContextCreateImage(bmContext); 181 | UIImage* contrasted = [UIImage imageWithCGImage:contrastedImageRef scale:self.scale orientation:self.imageOrientation]; 182 | 183 | /// Cleanup 184 | CGImageRelease(contrastedImageRef); 185 | free(dataAsFloat); 186 | CGContextRelease(bmContext); 187 | 188 | return contrasted; 189 | } 190 | 191 | -(UIImage*)edgeDetectionWithBias:(NSInteger)bias 192 | { 193 | #pragma unused(bias) 194 | /// Create an ARGB bitmap context 195 | const size_t width = (size_t)self.size.width; 196 | const size_t height = (size_t)self.size.height; 197 | const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel; 198 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow, NYXImageHasAlpha(self.CGImage)); 199 | if (!bmContext) 200 | return nil; 201 | 202 | /// Draw the image in the bitmap context 203 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 204 | 205 | /// Grab the image raw data 206 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 207 | if (!data) 208 | { 209 | CGContextRelease(bmContext); 210 | return nil; 211 | } 212 | 213 | /// vImage (iOS 5) works on simulator but not on device 214 | /*if ((&vImageConvolveWithBias_ARGB8888)) 215 | { 216 | const size_t n = sizeof(UInt8) * width * height * 4; 217 | void* outt = malloc(n); 218 | vImage_Buffer src = {data, height, width, bytesPerRow}; 219 | vImage_Buffer dest = {outt, height, width, bytesPerRow}; 220 | 221 | vImageConvolveWithBias_ARGB8888(&src, &dest, NULL, 0, 0, __s_edgedetect_kernel_3x3, 3, 3, 1, bias, NULL, kvImageCopyInPlace); 222 | 223 | CGDataProviderRef dp = CGDataProviderCreateWithData(NULL, data, n, NULL); 224 | 225 | CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); 226 | CGImageRef edgedImageRef = CGImageCreate(width, height, 8, 32, bytesPerRow, cs, kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipFirst, dp, NULL, true, kCGRenderingIntentDefault); 227 | CGColorSpaceRelease(cs); 228 | 229 | //memcpy(data, outt, n); 230 | //CGImageRef edgedImageRef = CGBitmapContextCreateImage(bmContext); 231 | UIImage* edged = [UIImage imageWithCGImage:edgedImageRef]; 232 | 233 | /// Cleanup 234 | CGImageRelease(edgedImageRef); 235 | CGDataProviderRelease(dp); 236 | free(outt); 237 | CGContextRelease(bmContext); 238 | 239 | return edged; 240 | } 241 | else 242 | {*/ 243 | const size_t pixelsCount = width * height; 244 | const size_t n = sizeof(float) * pixelsCount; 245 | float* dataAsFloat = malloc(n); 246 | float* resultAsFloat = malloc(n); 247 | float min = (float)kNyxMinPixelComponentValue, max = (float)kNyxMaxPixelComponentValue; 248 | 249 | /// Red components 250 | vDSP_vfltu8(data + 1, 4, dataAsFloat, 1, pixelsCount); 251 | vDSP_f3x3(dataAsFloat, height, width, __f_edgedetect_kernel_3x3, resultAsFloat); 252 | vDSP_vclip(resultAsFloat, 1, &min, &max, resultAsFloat, 1, pixelsCount); 253 | vDSP_vfixu8(resultAsFloat, 1, data + 1, 4, pixelsCount); 254 | 255 | /// Green components 256 | vDSP_vfltu8(data + 2, 4, dataAsFloat, 1, pixelsCount); 257 | vDSP_f3x3(dataAsFloat, height, width, __f_edgedetect_kernel_3x3, resultAsFloat); 258 | vDSP_vclip(resultAsFloat, 1, &min, &max, resultAsFloat, 1, pixelsCount); 259 | vDSP_vfixu8(resultAsFloat, 1, data + 2, 4, pixelsCount); 260 | 261 | /// Blue components 262 | vDSP_vfltu8(data + 3, 4, dataAsFloat, 1, pixelsCount); 263 | vDSP_f3x3(dataAsFloat, height, width, __f_edgedetect_kernel_3x3, resultAsFloat); 264 | vDSP_vclip(resultAsFloat, 1, &min, &max, resultAsFloat, 1, pixelsCount); 265 | vDSP_vfixu8(resultAsFloat, 1, data + 3, 4, pixelsCount); 266 | 267 | CGImageRef edgedImageRef = CGBitmapContextCreateImage(bmContext); 268 | UIImage* edged = [UIImage imageWithCGImage:edgedImageRef]; 269 | 270 | /// Cleanup 271 | CGImageRelease(edgedImageRef); 272 | free(resultAsFloat); 273 | free(dataAsFloat); 274 | CGContextRelease(bmContext); 275 | 276 | return edged; 277 | //} 278 | } 279 | 280 | -(UIImage*)embossWithBias:(NSInteger)bias 281 | { 282 | /// Create an ARGB bitmap context 283 | const size_t width = (size_t)self.size.width; 284 | const size_t height = (size_t)self.size.height; 285 | const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel; 286 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow, NYXImageHasAlpha(self.CGImage)); 287 | if (!bmContext) 288 | return nil; 289 | 290 | /// Draw the image in the bitmap context 291 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 292 | 293 | /// Grab the image raw data 294 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 295 | if (!data) 296 | { 297 | CGContextRelease(bmContext); 298 | return nil; 299 | } 300 | 301 | const size_t n = sizeof(UInt8) * width * height * 4; 302 | void* outt = malloc(n); 303 | vImage_Buffer src = {data, height, width, bytesPerRow}; 304 | vImage_Buffer dest = {outt, height, width, bytesPerRow}; 305 | vImageConvolveWithBias_ARGB8888(&src, &dest, NULL, 0, 0, __s_emboss_kernel_3x3, 3, 3, 1/*divisor*/, (int32_t)bias, NULL, kvImageCopyInPlace); 306 | 307 | memcpy(data, outt, n); 308 | 309 | free(outt); 310 | 311 | CGImageRef embossImageRef = CGBitmapContextCreateImage(bmContext); 312 | UIImage* emboss = [UIImage imageWithCGImage:embossImageRef]; 313 | 314 | /// Cleanup 315 | CGImageRelease(embossImageRef); 316 | CGContextRelease(bmContext); 317 | 318 | return emboss; 319 | } 320 | 321 | /// (0.01, 8) 322 | -(UIImage*)gammaCorrectionWithValue:(float)value 323 | { 324 | const size_t width = (size_t)self.size.width; 325 | const size_t height = (size_t)self.size.height; 326 | /// Number of bytes per row, each pixel in the bitmap will be represented by 4 bytes (ARGB), 8 bits of alpha/red/green/blue 327 | const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel; 328 | 329 | /// Create an ARGB bitmap context 330 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow, NYXImageHasAlpha(self.CGImage)); 331 | if (!bmContext) 332 | return nil; 333 | 334 | /// Draw the image in the bitmap context 335 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 336 | 337 | /// Grab the image raw data 338 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 339 | if (!data) 340 | { 341 | CGContextRelease(bmContext); 342 | return nil; 343 | } 344 | 345 | const size_t pixelsCount = width * height; 346 | const size_t n = sizeof(float) * pixelsCount; 347 | float* dataAsFloat = (float*)malloc(n); 348 | float* temp = (float*)malloc(n); 349 | float min = (float)kNyxMinPixelComponentValue, max = (float)kNyxMaxPixelComponentValue; 350 | const int iPixels = (int)pixelsCount; 351 | 352 | /// Need a vector with same size :( 353 | vDSP_vfill(&value, temp, 1, pixelsCount); 354 | 355 | /// Calculate red components 356 | vDSP_vfltu8(data + 1, 4, dataAsFloat, 1, pixelsCount); 357 | vDSP_vsdiv(dataAsFloat, 1, &max, dataAsFloat, 1, pixelsCount); 358 | vvpowf(dataAsFloat, temp, dataAsFloat, &iPixels); 359 | vDSP_vsmul(dataAsFloat, 1, &max, dataAsFloat, 1, pixelsCount); 360 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 361 | vDSP_vfixu8(dataAsFloat, 1, data + 1, 4, pixelsCount); 362 | 363 | /// Calculate green components 364 | vDSP_vfltu8(data + 2, 4, dataAsFloat, 1, pixelsCount); 365 | vDSP_vsdiv(dataAsFloat, 1, &max, dataAsFloat, 1, pixelsCount); 366 | vvpowf(dataAsFloat, temp, dataAsFloat, &iPixels); 367 | vDSP_vsmul(dataAsFloat, 1, &max, dataAsFloat, 1, pixelsCount); 368 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 369 | vDSP_vfixu8(dataAsFloat, 1, data + 2, 4, pixelsCount); 370 | 371 | /// Calculate blue components 372 | vDSP_vfltu8(data + 3, 4, dataAsFloat, 1, pixelsCount); 373 | vDSP_vsdiv(dataAsFloat, 1, &max, dataAsFloat, 1, pixelsCount); 374 | vvpowf(dataAsFloat, temp, dataAsFloat, &iPixels); 375 | vDSP_vsmul(dataAsFloat, 1, &max, dataAsFloat, 1, pixelsCount); 376 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 377 | vDSP_vfixu8(dataAsFloat, 1, data + 3, 4, pixelsCount); 378 | 379 | /// Cleanup 380 | free(temp); 381 | free(dataAsFloat); 382 | 383 | /// Create an image object from the context 384 | CGImageRef gammaImageRef = CGBitmapContextCreateImage(bmContext); 385 | UIImage* gamma = [UIImage imageWithCGImage:gammaImageRef]; 386 | 387 | /// Cleanup 388 | CGImageRelease(gammaImageRef); 389 | CGContextRelease(bmContext); 390 | 391 | return gamma; 392 | } 393 | 394 | -(UIImage*)grayscale 395 | { 396 | /* const UInt8 luminance = (red * 0.2126) + (green * 0.7152) + (blue * 0.0722); // Good luminance value */ 397 | /// Create a gray bitmap context 398 | const size_t width = (size_t)(self.size.width * self.scale); 399 | const size_t height = (size_t)(self.size.height * self.scale); 400 | 401 | CGRect imageRect = CGRectMake(0, 0, width, height); 402 | 403 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 404 | CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8/*Bits per component*/, width * kNyxNumberOfComponentsPerGreyPixel, colorSpace, (CGBitmapInfo)kCGImageAlphaNone); 405 | CGColorSpaceRelease(colorSpace); 406 | if (!bmContext) 407 | return nil; 408 | 409 | /// Image quality 410 | CGContextSetShouldAntialias(bmContext, false); 411 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 412 | 413 | /// Draw the image in the bitmap context 414 | CGContextDrawImage(bmContext, imageRect, self.CGImage); 415 | 416 | /// Create an image object from the context 417 | CGImageRef grayscaledImageRef = CGBitmapContextCreateImage(bmContext); 418 | 419 | // Preserve alpha channel by creating context with 'alpha only' values 420 | // and using it as a mask for previously generated `grayscaledImageRef` 421 | // based on: http://incurlybraces.com/convert-transparent-image-to-grayscale-in-ios.html 422 | bmContext = CGBitmapContextCreate(nil, width, height, 8, width, nil, (CGBitmapInfo) kCGImageAlphaOnly); 423 | CGContextDrawImage(bmContext, imageRect, [self CGImage]); 424 | CGImageRef mask = CGBitmapContextCreateImage(bmContext); 425 | UIImage *grayscaled = [UIImage imageWithCGImage:CGImageCreateWithMask(grayscaledImageRef, mask) scale:self.scale orientation:self.imageOrientation]; 426 | 427 | /// Cleanup 428 | CGImageRelease(grayscaledImageRef); 429 | CGContextRelease(bmContext); 430 | 431 | return grayscaled; 432 | } 433 | 434 | -(UIImage*)invert 435 | { 436 | /// Create an ARGB bitmap context 437 | const size_t width = (size_t)self.size.width; 438 | const size_t height = (size_t)self.size.height; 439 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, width * kNyxNumberOfComponentsPerARBGPixel, NYXImageHasAlpha(self.CGImage)); 440 | if (!bmContext) 441 | return nil; 442 | 443 | /// Draw the image in the bitmap context 444 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 445 | 446 | /// Grab the image raw data 447 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 448 | if (!data) 449 | { 450 | CGContextRelease(bmContext); 451 | return nil; 452 | } 453 | 454 | const size_t pixelsCount = width * height; 455 | float* dataAsFloat = (float*)malloc(sizeof(float) * pixelsCount); 456 | float min = (float)kNyxMinPixelComponentValue, max = (float)kNyxMaxPixelComponentValue; 457 | UInt8* dataRed = data + 1; 458 | UInt8* dataGreen = data + 2; 459 | UInt8* dataBlue = data + 3; 460 | 461 | /// vDSP_vsmsa() = multiply then add 462 | /// slightly faster than the couple vDSP_vneg() & vDSP_vsadd() 463 | /// Probably because there are 3 function calls less 464 | 465 | /// Calculate red components 466 | vDSP_vfltu8(dataRed, 4, dataAsFloat, 1, pixelsCount); 467 | vDSP_vsmsa(dataAsFloat, 1, &__negativeMultiplier, &max, dataAsFloat, 1, pixelsCount); 468 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 469 | vDSP_vfixu8(dataAsFloat, 1, dataRed, 4, pixelsCount); 470 | 471 | /// Calculate green components 472 | vDSP_vfltu8(dataGreen, 4, dataAsFloat, 1, pixelsCount); 473 | vDSP_vsmsa(dataAsFloat, 1, &__negativeMultiplier, &max, dataAsFloat, 1, pixelsCount); 474 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 475 | vDSP_vfixu8(dataAsFloat, 1, dataGreen, 4, pixelsCount); 476 | 477 | /// Calculate blue components 478 | vDSP_vfltu8(dataBlue, 4, dataAsFloat, 1, pixelsCount); 479 | vDSP_vsmsa(dataAsFloat, 1, &__negativeMultiplier, &max, dataAsFloat, 1, pixelsCount); 480 | vDSP_vclip(dataAsFloat, 1, &min, &max, dataAsFloat, 1, pixelsCount); 481 | vDSP_vfixu8(dataAsFloat, 1, dataBlue, 4, pixelsCount); 482 | 483 | CGImageRef invertedImageRef = CGBitmapContextCreateImage(bmContext); 484 | UIImage* inverted = [UIImage imageWithCGImage:invertedImageRef]; 485 | 486 | /// Cleanup 487 | CGImageRelease(invertedImageRef); 488 | free(dataAsFloat); 489 | CGContextRelease(bmContext); 490 | 491 | return inverted; 492 | } 493 | 494 | -(UIImage*)opacity:(float)value 495 | { 496 | /// Create an ARGB bitmap context 497 | const size_t width = (size_t)self.size.width; 498 | const size_t height = (size_t)self.size.height; 499 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, width * kNyxNumberOfComponentsPerARBGPixel, YES); 500 | if (!bmContext) 501 | return nil; 502 | 503 | /// Set the alpha value and draw the image in the bitmap context 504 | CGContextSetAlpha(bmContext, value); 505 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 506 | 507 | /// Create an image object from the context 508 | CGImageRef transparentImageRef = CGBitmapContextCreateImage(bmContext); 509 | UIImage* transparent = [UIImage imageWithCGImage:transparentImageRef]; 510 | 511 | /// Cleanup 512 | CGImageRelease(transparentImageRef); 513 | CGContextRelease(bmContext); 514 | 515 | return transparent; 516 | } 517 | 518 | -(UIImage*)sepia 519 | { 520 | if ([CIImage class]) 521 | { 522 | /// The sepia output from Core Image is nicer than manual method and 1.6x faster than vDSP 523 | CIImage* ciImage = [[CIImage alloc] initWithCGImage:self.CGImage]; 524 | CIImage* output = [CIFilter filterWithName:@"CISepiaTone" keysAndValues:kCIInputImageKey, ciImage, @"inputIntensity", [NSNumber numberWithFloat:1.0f], nil].outputImage; 525 | CGImageRef cgImage = [NYXGetCIContext() createCGImage:output fromRect:[output extent]]; 526 | UIImage* sepia = [UIImage imageWithCGImage:cgImage]; 527 | CGImageRelease(cgImage); 528 | return sepia; 529 | } 530 | else 531 | { 532 | /* 1.6x faster than before */ 533 | /// Create an ARGB bitmap context 534 | const size_t width = (size_t)self.size.width; 535 | const size_t height = (size_t)self.size.height; 536 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, width * kNyxNumberOfComponentsPerARBGPixel, NYXImageHasAlpha(self.CGImage)); 537 | if (!bmContext) 538 | return nil; 539 | 540 | /// Draw the image in the bitmap context 541 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 542 | 543 | /// Grab the image raw data 544 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 545 | if (!data) 546 | { 547 | CGContextRelease(bmContext); 548 | return nil; 549 | } 550 | 551 | const size_t pixelsCount = width * height; 552 | const size_t n = sizeof(float) * pixelsCount; 553 | float* reds = (float*)malloc(n); 554 | float* greens = (float*)malloc(n); 555 | float* blues = (float*)malloc(n); 556 | float* tmpRed = (float*)malloc(n); 557 | float* tmpGreen = (float*)malloc(n); 558 | float* tmpBlue = (float*)malloc(n); 559 | float* finalRed = (float*)malloc(n); 560 | float* finalGreen = (float*)malloc(n); 561 | float* finalBlue = (float*)malloc(n); 562 | float min = (float)kNyxMinPixelComponentValue, max = (float)kNyxMaxPixelComponentValue; 563 | 564 | /// Convert byte components to float 565 | vDSP_vfltu8(data + 1, 4, reds, 1, pixelsCount); 566 | vDSP_vfltu8(data + 2, 4, greens, 1, pixelsCount); 567 | vDSP_vfltu8(data + 3, 4, blues, 1, pixelsCount); 568 | 569 | /// Calculate red components 570 | vDSP_vsmul(reds, 1, &__sepiaFactorRedRed, tmpRed, 1, pixelsCount); 571 | vDSP_vsmul(greens, 1, &__sepiaFactorGreenRed, tmpGreen, 1, pixelsCount); 572 | vDSP_vsmul(blues, 1, &__sepiaFactorBlueRed, tmpBlue, 1, pixelsCount); 573 | vDSP_vadd(tmpRed, 1, tmpGreen, 1, finalRed, 1, pixelsCount); 574 | vDSP_vadd(finalRed, 1, tmpBlue, 1, finalRed, 1, pixelsCount); 575 | vDSP_vclip(finalRed, 1, &min, &max, finalRed, 1, pixelsCount); 576 | vDSP_vfixu8(finalRed, 1, data + 1, 4, pixelsCount); 577 | 578 | /// Calculate green components 579 | vDSP_vsmul(reds, 1, &__sepiaFactorRedGreen, tmpRed, 1, pixelsCount); 580 | vDSP_vsmul(greens, 1, &__sepiaFactorGreenGreen, tmpGreen, 1, pixelsCount); 581 | vDSP_vsmul(blues, 1, &__sepiaFactorBlueGreen, tmpBlue, 1, pixelsCount); 582 | vDSP_vadd(tmpRed, 1, tmpGreen, 1, finalGreen, 1, pixelsCount); 583 | vDSP_vadd(finalGreen, 1, tmpBlue, 1, finalGreen, 1, pixelsCount); 584 | vDSP_vclip(finalGreen, 1, &min, &max, finalGreen, 1, pixelsCount); 585 | vDSP_vfixu8(finalGreen, 1, data + 2, 4, pixelsCount); 586 | 587 | /// Calculate blue components 588 | vDSP_vsmul(reds, 1, &__sepiaFactorRedBlue, tmpRed, 1, pixelsCount); 589 | vDSP_vsmul(greens, 1, &__sepiaFactorGreenBlue, tmpGreen, 1, pixelsCount); 590 | vDSP_vsmul(blues, 1, &__sepiaFactorBlueBlue, tmpBlue, 1, pixelsCount); 591 | vDSP_vadd(tmpRed, 1, tmpGreen, 1, finalBlue, 1, pixelsCount); 592 | vDSP_vadd(finalBlue, 1, tmpBlue, 1, finalBlue, 1, pixelsCount); 593 | vDSP_vclip(finalBlue, 1, &min, &max, finalBlue, 1, pixelsCount); 594 | vDSP_vfixu8(finalBlue, 1, data + 3, 4, pixelsCount); 595 | 596 | /// Create an image object from the context 597 | CGImageRef sepiaImageRef = CGBitmapContextCreateImage(bmContext); 598 | UIImage* sepia = [UIImage imageWithCGImage:sepiaImageRef]; 599 | 600 | /// Cleanup 601 | CGImageRelease(sepiaImageRef); 602 | free(reds), free(greens), free(blues), free(tmpRed), free(tmpGreen), free(tmpBlue), free(finalRed), free(finalGreen), free(finalBlue); 603 | CGContextRelease(bmContext); 604 | 605 | return sepia; 606 | } 607 | } 608 | 609 | -(UIImage*)sharpenWithBias:(NSInteger)bias 610 | { 611 | /// Create an ARGB bitmap context 612 | const size_t width = (size_t)self.size.width; 613 | const size_t height = (size_t)self.size.height; 614 | const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel; 615 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow, NYXImageHasAlpha(self.CGImage)); 616 | if (!bmContext) 617 | return nil; 618 | 619 | /// Draw the image in the bitmap context 620 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 621 | 622 | /// Grab the image raw data 623 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 624 | if (!data) 625 | { 626 | CGContextRelease(bmContext); 627 | return nil; 628 | } 629 | 630 | const size_t n = sizeof(UInt8) * width * height * 4; 631 | void* outt = malloc(n); 632 | vImage_Buffer src = {data, height, width, bytesPerRow}; 633 | vImage_Buffer dest = {outt, height, width, bytesPerRow}; 634 | vImageConvolveWithBias_ARGB8888(&src, &dest, NULL, 0, 0, __s_sharpen_kernel_3x3, 3, 3, 1/*divisor*/, (int32_t)bias, NULL, kvImageCopyInPlace); 635 | 636 | memcpy(data, outt, n); 637 | 638 | free(outt); 639 | 640 | CGImageRef sharpenedImageRef = CGBitmapContextCreateImage(bmContext); 641 | UIImage* sharpened = [UIImage imageWithCGImage:sharpenedImageRef]; 642 | 643 | /// Cleanup 644 | CGImageRelease(sharpenedImageRef); 645 | CGContextRelease(bmContext); 646 | 647 | return sharpened; 648 | } 649 | 650 | -(UIImage*)unsharpenWithBias:(NSInteger)bias 651 | { 652 | /// Create an ARGB bitmap context 653 | const size_t width = (size_t)self.size.width; 654 | const size_t height = (size_t)self.size.height; 655 | const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel; 656 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow, NYXImageHasAlpha(self.CGImage)); 657 | if (!bmContext) 658 | return nil; 659 | 660 | /// Draw the image in the bitmap context 661 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 662 | 663 | /// Grab the image raw data 664 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 665 | if (!data) 666 | { 667 | CGContextRelease(bmContext); 668 | return nil; 669 | } 670 | 671 | const size_t n = sizeof(UInt8) * width * height * 4; 672 | void* outt = malloc(n); 673 | vImage_Buffer src = {data, height, width, bytesPerRow}; 674 | vImage_Buffer dest = {outt, height, width, bytesPerRow}; 675 | vImageConvolveWithBias_ARGB8888(&src, &dest, NULL, 0, 0, __s_unsharpen_kernel_3x3, 3, 3, 9/*divisor*/, (int32_t)bias, NULL, kvImageCopyInPlace); 676 | 677 | memcpy(data, outt, n); 678 | 679 | free(outt); 680 | 681 | CGImageRef unsharpenedImageRef = CGBitmapContextCreateImage(bmContext); 682 | UIImage* unsharpened = [UIImage imageWithCGImage:unsharpenedImageRef]; 683 | 684 | /// Cleanup 685 | CGImageRelease(unsharpenedImageRef); 686 | CGContextRelease(bmContext); 687 | 688 | return unsharpened; 689 | } 690 | 691 | @end 692 | -------------------------------------------------------------------------------- /Categories/UIImage+Masking.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Masking.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/06/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | @interface UIImage (NYX_Masking) 15 | 16 | -(UIImage*)maskWithImage:(UIImage*)mask; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Categories/UIImage+Masking.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Masking.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/06/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Masking.h" 12 | 13 | 14 | @implementation UIImage (NYX_Masking) 15 | 16 | -(UIImage*)maskWithImage:(UIImage*)maskImage 17 | { 18 | /// Create a bitmap context with valid alpha 19 | const size_t originalWidth = (size_t)(self.size.width * self.scale); 20 | const size_t originalHeight = (size_t)(self.size.height * self.scale); 21 | CGContextRef bmContext = NYXCreateARGBBitmapContext(originalWidth, originalHeight, 0, YES); 22 | if (!bmContext) 23 | return nil; 24 | 25 | /// Image quality 26 | CGContextSetShouldAntialias(bmContext, true); 27 | CGContextSetAllowsAntialiasing(bmContext, true); 28 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 29 | 30 | /// Image mask 31 | CGImageRef cgMaskImage = maskImage.CGImage; 32 | CGImageRef mask = CGImageMaskCreate((size_t)maskImage.size.width, (size_t)maskImage.size.height, CGImageGetBitsPerComponent(cgMaskImage), CGImageGetBitsPerPixel(cgMaskImage), CGImageGetBytesPerRow(cgMaskImage), CGImageGetDataProvider(cgMaskImage), NULL, false); 33 | 34 | /// Draw the original image in the bitmap context 35 | const CGRect r = (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = originalWidth, .size.height = originalHeight}; 36 | CGContextClipToMask(bmContext, r, cgMaskImage); 37 | CGContextDrawImage(bmContext, r, self.CGImage); 38 | 39 | /// Get the CGImage object 40 | CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(bmContext); 41 | /// Apply the mask 42 | CGImageRef maskedImageRef = CGImageCreateWithMask(imageRefWithAlpha, mask); 43 | 44 | UIImage* result = [UIImage imageWithCGImage:maskedImageRef scale:self.scale orientation:self.imageOrientation]; 45 | 46 | /// Cleanup 47 | CGImageRelease(maskedImageRef); 48 | CGImageRelease(imageRefWithAlpha); 49 | CGContextRelease(bmContext); 50 | CGImageRelease(mask); 51 | 52 | return result; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Categories/UIImage+Reflection.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Reflection.h 3 | // NYXImagesKit 4 | // 5 | // Created by Matthias Tretter (@myell0w) on 02.06.11. 6 | 7 | // This was taken from the increadibly awesome HockeyKit: 8 | // Originally Created by Peter Steinberger on 10.01.11. 9 | // Copyright 2012 Peter Steinberger. All rights reserved. 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | #import "NYXImagesHelper.h" 31 | 32 | 33 | @interface UIImage (NYX_Reflection) 34 | 35 | -(UIImage*)reflectedImageWithHeight:(NSUInteger)height fromAlpha:(float)fromAlpha toAlpha:(float)toAlpha; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Categories/UIImage+Reflection.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Reflection.m 3 | // NYXImagesKit 4 | // 5 | // Created by Matthias Tretter (@myell0w) on 02.06.11. 6 | 7 | // This was taken from the increadibly awesome HockeyKit: 8 | // Originally Created by Peter Steinberger on 10.01.11. 9 | // Copyright 2012 Peter Steinberger. All rights reserved. 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | #import "UIImage+Reflection.h" 31 | 32 | 33 | @implementation UIImage (NYX_Reflection) 34 | 35 | -(UIImage*)reflectedImageWithHeight:(NSUInteger)height fromAlpha:(float)fromAlpha toAlpha:(float)toAlpha 36 | { 37 | if (!height) 38 | return nil; 39 | 40 | // create a bitmap graphics context the size of the image 41 | UIGraphicsBeginImageContextWithOptions((CGSize){.width = self.size.width, .height = height}, NO, 0.0f); 42 | CGContextRef mainViewContentContext = UIGraphicsGetCurrentContext(); 43 | 44 | // create a 2 bit CGImage containing a gradient that will be used for masking the 45 | // main view content to create the 'fade' of the reflection. The CGImageCreateWithMask 46 | // function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient 47 | CGImageRef gradientMaskImage = NYXCreateGradientImage(1, height, fromAlpha, toAlpha); 48 | 49 | // create an image by masking the bitmap of the mainView content with the gradient view 50 | // then release the pre-masked content bitmap and the gradient bitmap 51 | CGContextClipToMask(mainViewContentContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = self.size.width, .size.height = height}, gradientMaskImage); 52 | CGImageRelease(gradientMaskImage); 53 | 54 | // draw the image into the bitmap context 55 | CGContextDrawImage(mainViewContentContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size = self.size}, self.CGImage); 56 | 57 | // convert the finished reflection image to a UIImage 58 | UIImage* theImage = UIGraphicsGetImageFromCurrentImageContext(); 59 | 60 | UIGraphicsEndImageContext(); 61 | 62 | return theImage; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Categories/UIImage+Resizing.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Resize.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | typedef enum 15 | { 16 | NYXCropModeTopLeft, 17 | NYXCropModeTopCenter, 18 | NYXCropModeTopRight, 19 | NYXCropModeBottomLeft, 20 | NYXCropModeBottomCenter, 21 | NYXCropModeBottomRight, 22 | NYXCropModeLeftCenter, 23 | NYXCropModeRightCenter, 24 | NYXCropModeCenter 25 | } NYXCropMode; 26 | 27 | typedef enum 28 | { 29 | NYXResizeModeScaleToFill, 30 | NYXResizeModeAspectFit, 31 | NYXResizeModeAspectFill 32 | } NYXResizeMode; 33 | 34 | 35 | @interface UIImage (NYX_Resizing) 36 | 37 | -(UIImage*)cropToSize:(CGSize)newSize usingMode:(NYXCropMode)cropMode; 38 | 39 | // NYXCropModeTopLeft crop mode used 40 | -(UIImage*)cropToSize:(CGSize)newSize; 41 | 42 | -(UIImage*)scaleByFactor:(float)scaleFactor; 43 | 44 | -(UIImage*)scaleToSize:(CGSize)newSize usingMode:(NYXResizeMode)resizeMode; 45 | 46 | // NYXResizeModeScaleToFill resize mode used 47 | -(UIImage*)scaleToSize:(CGSize)newSize; 48 | 49 | // Same as 'scale to fill' in IB. 50 | -(UIImage*)scaleToFillSize:(CGSize)newSize; 51 | 52 | // Preserves aspect ratio. Same as 'aspect fit' in IB. 53 | -(UIImage*)scaleToFitSize:(CGSize)newSize; 54 | 55 | // Preserves aspect ratio. Same as 'aspect fill' in IB. 56 | -(UIImage*)scaleToCoverSize:(CGSize)newSize; 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /Categories/UIImage+Resizing.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Resize.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Resizing.h" 12 | 13 | 14 | @implementation UIImage (NYX_Resizing) 15 | 16 | -(UIImage*)cropToSize:(CGSize)newSize usingMode:(NYXCropMode)cropMode 17 | { 18 | const CGSize size = self.size; 19 | CGFloat x, y; 20 | switch (cropMode) 21 | { 22 | case NYXCropModeTopLeft: 23 | x = y = 0.0f; 24 | break; 25 | case NYXCropModeTopCenter: 26 | x = (size.width - newSize.width) * 0.5f; 27 | y = 0.0f; 28 | break; 29 | case NYXCropModeTopRight: 30 | x = size.width - newSize.width; 31 | y = 0.0f; 32 | break; 33 | case NYXCropModeBottomLeft: 34 | x = 0.0f; 35 | y = size.height - newSize.height; 36 | break; 37 | case NYXCropModeBottomCenter: 38 | x = (size.width - newSize.width) * 0.5f; 39 | y = size.height - newSize.height; 40 | break; 41 | case NYXCropModeBottomRight: 42 | x = size.width - newSize.width; 43 | y = size.height - newSize.height; 44 | break; 45 | case NYXCropModeLeftCenter: 46 | x = 0.0f; 47 | y = (size.height - newSize.height) * 0.5f; 48 | break; 49 | case NYXCropModeRightCenter: 50 | x = size.width - newSize.width; 51 | y = (size.height - newSize.height) * 0.5f; 52 | break; 53 | case NYXCropModeCenter: 54 | x = (size.width - newSize.width) * 0.5f; 55 | y = (size.height - newSize.height) * 0.5f; 56 | break; 57 | default: // Default to top left 58 | x = y = 0.0f; 59 | break; 60 | } 61 | 62 | if (self.imageOrientation == UIImageOrientationLeft || self.imageOrientation == UIImageOrientationLeftMirrored || self.imageOrientation == UIImageOrientationRight || self.imageOrientation == UIImageOrientationRightMirrored) 63 | { 64 | CGFloat temp = x; 65 | x = y; 66 | y = temp; 67 | 68 | temp = newSize.width; 69 | newSize.width = newSize.height; 70 | newSize.height = temp; 71 | } 72 | 73 | CGRect cropRect = CGRectMake(x * self.scale, y * self.scale, newSize.width * self.scale, newSize.height * self.scale); 74 | 75 | /// Create the cropped image 76 | CGImageRef croppedImageRef = CGImageCreateWithImageInRect(self.CGImage, cropRect); 77 | UIImage* cropped = [UIImage imageWithCGImage:croppedImageRef scale:self.scale orientation:self.imageOrientation]; 78 | 79 | /// Cleanup 80 | CGImageRelease(croppedImageRef); 81 | 82 | return cropped; 83 | } 84 | 85 | /* Convenience method to crop the image from the top left corner */ 86 | -(UIImage*)cropToSize:(CGSize)newSize 87 | { 88 | return [self cropToSize:newSize usingMode:NYXCropModeTopLeft]; 89 | } 90 | 91 | -(UIImage*)scaleByFactor:(float)scaleFactor 92 | { 93 | CGSize scaledSize = CGSizeMake(self.size.width * scaleFactor, self.size.height * scaleFactor); 94 | return [self scaleToFillSize:scaledSize]; 95 | } 96 | 97 | -(UIImage*)scaleToSize:(CGSize)newSize usingMode:(NYXResizeMode)resizeMode 98 | { 99 | switch (resizeMode) 100 | { 101 | case NYXResizeModeAspectFit: 102 | return [self scaleToFitSize:newSize]; 103 | case NYXResizeModeAspectFill: 104 | return [self scaleToCoverSize:newSize]; 105 | default: 106 | return [self scaleToFillSize:newSize]; 107 | } 108 | } 109 | 110 | /* Convenience method to scale the image using the NYXResizeModeScaleToFill mode */ 111 | -(UIImage*)scaleToSize:(CGSize)newSize 112 | { 113 | return [self scaleToFillSize:newSize]; 114 | } 115 | 116 | -(UIImage*)scaleToFillSize:(CGSize)newSize 117 | { 118 | size_t destWidth = (size_t)(newSize.width * self.scale); 119 | size_t destHeight = (size_t)(newSize.height * self.scale); 120 | if (self.imageOrientation == UIImageOrientationLeft 121 | || self.imageOrientation == UIImageOrientationLeftMirrored 122 | || self.imageOrientation == UIImageOrientationRight 123 | || self.imageOrientation == UIImageOrientationRightMirrored) 124 | { 125 | size_t temp = destWidth; 126 | destWidth = destHeight; 127 | destHeight = temp; 128 | } 129 | 130 | /// Create an ARGB bitmap context 131 | CGContextRef bmContext = NYXCreateARGBBitmapContext(destWidth, destHeight, destWidth * kNyxNumberOfComponentsPerARBGPixel, NYXImageHasAlpha(self.CGImage)); 132 | if (!bmContext) 133 | return nil; 134 | 135 | /// Image quality 136 | CGContextSetShouldAntialias(bmContext, true); 137 | CGContextSetAllowsAntialiasing(bmContext, true); 138 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 139 | 140 | /// Draw the image in the bitmap context 141 | 142 | UIGraphicsPushContext(bmContext); 143 | CGContextDrawImage(bmContext, CGRectMake(0.0f, 0.0f, destWidth, destHeight), self.CGImage); 144 | UIGraphicsPopContext(); 145 | 146 | /// Create an image object from the context 147 | CGImageRef scaledImageRef = CGBitmapContextCreateImage(bmContext); 148 | UIImage* scaled = [UIImage imageWithCGImage:scaledImageRef scale:self.scale orientation:self.imageOrientation]; 149 | 150 | /// Cleanup 151 | CGImageRelease(scaledImageRef); 152 | CGContextRelease(bmContext); 153 | 154 | return scaled; 155 | } 156 | 157 | -(UIImage*)scaleToFitSize:(CGSize)newSize 158 | { 159 | /// Keep aspect ratio 160 | size_t destWidth, destHeight; 161 | if (self.size.width > self.size.height) 162 | { 163 | destWidth = (size_t)newSize.width; 164 | destHeight = (size_t)(self.size.height * newSize.width / self.size.width); 165 | } 166 | else 167 | { 168 | destHeight = (size_t)newSize.height; 169 | destWidth = (size_t)(self.size.width * newSize.height / self.size.height); 170 | } 171 | if (destWidth > newSize.width) 172 | { 173 | destWidth = (size_t)newSize.width; 174 | destHeight = (size_t)(self.size.height * newSize.width / self.size.width); 175 | } 176 | if (destHeight > newSize.height) 177 | { 178 | destHeight = (size_t)newSize.height; 179 | destWidth = (size_t)(self.size.width * newSize.height / self.size.height); 180 | } 181 | return [self scaleToFillSize:CGSizeMake(destWidth, destHeight)]; 182 | } 183 | 184 | -(UIImage*)scaleToCoverSize:(CGSize)newSize 185 | { 186 | size_t destWidth, destHeight; 187 | CGFloat widthRatio = newSize.width / self.size.width; 188 | CGFloat heightRatio = newSize.height / self.size.height; 189 | /// Keep aspect ratio 190 | if (heightRatio > widthRatio) 191 | { 192 | destHeight = (size_t)newSize.height; 193 | destWidth = (size_t)(self.size.width * newSize.height / self.size.height); 194 | } 195 | else 196 | { 197 | destWidth = (size_t)newSize.width; 198 | destHeight = (size_t)(self.size.height * newSize.width / self.size.width); 199 | } 200 | return [self scaleToFillSize:CGSizeMake(destWidth, destHeight)]; 201 | } 202 | 203 | @end 204 | -------------------------------------------------------------------------------- /Categories/UIImage+Rotating.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Rotation.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | @interface UIImage (NYX_Rotating) 15 | 16 | -(UIImage*)rotateInRadians:(float)radians; 17 | 18 | -(UIImage*)rotateInDegrees:(float)degrees; 19 | 20 | -(UIImage*)rotateImagePixelsInRadians:(float)radians; 21 | 22 | -(UIImage*)rotateImagePixelsInDegrees:(float)degrees; 23 | 24 | -(UIImage*)verticalFlip; 25 | 26 | -(UIImage*)horizontalFlip; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Categories/UIImage+Rotating.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Rotation.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Rotating.h" 12 | #import 13 | #import 14 | 15 | @implementation UIImage (NYX_Rotating) 16 | 17 | -(UIImage*)rotateInRadians:(CGFloat)radians flipOverHorizontalAxis:(BOOL)doHorizontalFlip verticalAxis:(BOOL)doVerticalFlip 18 | { 19 | /// Create an ARGB bitmap context 20 | const size_t width = (size_t)CGImageGetWidth(self.CGImage); 21 | const size_t height = (size_t)CGImageGetHeight(self.CGImage); 22 | 23 | CGRect rotatedRect = CGRectApplyAffineTransform(CGRectMake(0., 0., width, height), CGAffineTransformMakeRotation(radians)); 24 | 25 | CGContextRef bmContext = NYXCreateARGBBitmapContext((size_t)rotatedRect.size.width, (size_t)rotatedRect.size.height, (size_t)rotatedRect.size.width * kNyxNumberOfComponentsPerARBGPixel, YES); 26 | if (!bmContext) 27 | return nil; 28 | 29 | /// Image quality 30 | CGContextSetShouldAntialias(bmContext, true); 31 | CGContextSetAllowsAntialiasing(bmContext, true); 32 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 33 | 34 | /// Rotation happen here (around the center) 35 | CGContextTranslateCTM(bmContext, +(rotatedRect.size.width / 2.0f), +(rotatedRect.size.height / 2.0f)); 36 | CGContextRotateCTM(bmContext, radians); 37 | 38 | // Do flips 39 | CGContextScaleCTM(bmContext, (doHorizontalFlip ? -1.0f : 1.0f), (doVerticalFlip ? -1.0f : 1.0f)); 40 | 41 | /// Draw the image in the bitmap context 42 | CGContextDrawImage(bmContext, CGRectMake(-(width / 2.0f), -(height / 2.0f), width, height), self.CGImage); 43 | 44 | /// Create an image object from the context 45 | CGImageRef resultImageRef = CGBitmapContextCreateImage(bmContext); 46 | UIImage* resultImage = [UIImage imageWithCGImage:resultImageRef scale:self.scale orientation:self.imageOrientation]; 47 | 48 | /// Cleanup 49 | CGImageRelease(resultImageRef); 50 | CGContextRelease(bmContext); 51 | 52 | return resultImage; 53 | } 54 | 55 | -(UIImage*)rotateInRadians:(float)radians 56 | { 57 | return [self rotateInRadians:radians flipOverHorizontalAxis:NO verticalAxis:NO]; 58 | } 59 | 60 | -(UIImage*)rotateInDegrees:(float)degrees 61 | { 62 | return [self rotateInRadians:(float)NYX_DEGREES_TO_RADIANS(degrees)]; 63 | } 64 | 65 | -(UIImage*)verticalFlip 66 | { 67 | return [self rotateInRadians:0. flipOverHorizontalAxis:NO verticalAxis:YES]; 68 | } 69 | 70 | -(UIImage*)horizontalFlip 71 | { 72 | return [self rotateInRadians:0. flipOverHorizontalAxis:YES verticalAxis:NO]; 73 | } 74 | 75 | -(UIImage*)rotateImagePixelsInRadians:(float)radians 76 | { 77 | /// Create an ARGB bitmap context 78 | const size_t width = (size_t)(self.size.width * self.scale); 79 | const size_t height = (size_t)(self.size.height * self.scale); 80 | const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel; 81 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow, YES); 82 | if (!bmContext) 83 | return nil; 84 | 85 | /// Draw the image in the bitmap context 86 | CGContextDrawImage(bmContext, CGRectMake(0.0f, 0.0f, width, height), self.CGImage); 87 | 88 | /// Grab the image raw data 89 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 90 | if (!data) 91 | { 92 | CGContextRelease(bmContext); 93 | return nil; 94 | } 95 | 96 | vImage_Buffer src = {data, height, width, bytesPerRow}; 97 | vImage_Buffer dest = {data, height, width, bytesPerRow}; 98 | Pixel_8888 bgColor = {0, 0, 0, 0}; 99 | vImageRotate_ARGB8888(&src, &dest, NULL, radians, bgColor, kvImageBackgroundColorFill); 100 | 101 | CGImageRef rotatedImageRef = CGBitmapContextCreateImage(bmContext); 102 | UIImage* rotated = [UIImage imageWithCGImage:rotatedImageRef scale:self.scale orientation:self.imageOrientation]; 103 | 104 | /// Cleanup 105 | CGImageRelease(rotatedImageRef); 106 | CGContextRelease(bmContext); 107 | 108 | return rotated; 109 | } 110 | 111 | -(UIImage*)rotateImagePixelsInDegrees:(float)degrees 112 | { 113 | return [self rotateImagePixelsInRadians:(float)NYX_DEGREES_TO_RADIANS(degrees)]; 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /Categories/UIImage+Saving.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Saving.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 05/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | typedef enum 15 | { 16 | NYXImageTypePNG, 17 | NYXImageTypeJPEG, 18 | NYXImageTypeGIF, 19 | NYXImageTypeBMP, 20 | NYXImageTypeTIFF 21 | } NYXImageType; 22 | 23 | 24 | @interface UIImage (NYX_Saving) 25 | 26 | -(BOOL)saveToURL:(NSURL*)url uti:(CFStringRef)uti backgroundFillColor:(UIColor*)fillColor; 27 | 28 | -(BOOL)saveToURL:(NSURL*)url type:(NYXImageType)type backgroundFillColor:(UIColor*)fillColor; 29 | 30 | -(BOOL)saveToURL:(NSURL*)url; 31 | 32 | -(BOOL)saveToPath:(NSString*)path uti:(CFStringRef)uti backgroundFillColor:(UIColor*)fillColor; 33 | 34 | -(BOOL)saveToPath:(NSString*)path type:(NYXImageType)type backgroundFillColor:(UIColor*)fillColor; 35 | 36 | -(BOOL)saveToPath:(NSString*)path; 37 | 38 | -(BOOL)saveToPhotosAlbum; 39 | 40 | +(NSString*)extensionForUTI:(CFStringRef)uti; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Categories/UIImage+Saving.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Saving.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 05/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Saving.h" 12 | #import // For CGImageDestination 13 | #import // For the UTI types constants 14 | #import // For photos album saving 15 | 16 | 17 | @interface UIImage (NYX_Saving_private) 18 | -(CFStringRef)utiForType:(NYXImageType)type; 19 | @end 20 | 21 | 22 | @implementation UIImage (NYX_Saving) 23 | 24 | -(BOOL)saveToURL:(NSURL*)url uti:(CFStringRef)uti backgroundFillColor:(UIColor*)fillColor 25 | { 26 | if (!url) 27 | return NO; 28 | 29 | if (!uti) 30 | uti = kUTTypePNG; 31 | 32 | CGImageDestinationRef dest = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, uti, 1, NULL); 33 | if (!dest) 34 | return NO; 35 | 36 | /// Set the options, 1 -> lossless 37 | CFMutableDictionaryRef options = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 38 | if (!options) 39 | { 40 | CFRelease(dest); 41 | return NO; 42 | } 43 | CFDictionaryAddValue(options, kCGImageDestinationLossyCompressionQuality, (__bridge CFNumberRef)[NSNumber numberWithFloat:1.0f]); // No compression 44 | if (fillColor) 45 | CFDictionaryAddValue(options, kCGImageDestinationBackgroundColor, fillColor.CGColor); 46 | 47 | /// Add the image 48 | CGImageDestinationAddImage(dest, self.CGImage, (CFDictionaryRef)options); 49 | 50 | /// Write it to the destination 51 | const bool success = CGImageDestinationFinalize(dest); 52 | 53 | /// Cleanup 54 | CFRelease(options); 55 | CFRelease(dest); 56 | 57 | return success; 58 | } 59 | 60 | -(BOOL)saveToURL:(NSURL*)url type:(NYXImageType)type backgroundFillColor:(UIColor*)fillColor 61 | { 62 | return [self saveToURL:url uti:[self utiForType:type] backgroundFillColor:fillColor]; 63 | } 64 | 65 | -(BOOL)saveToURL:(NSURL*)url 66 | { 67 | return [self saveToURL:url uti:kUTTypePNG backgroundFillColor:nil]; 68 | } 69 | 70 | -(BOOL)saveToPath:(NSString*)path uti:(CFStringRef)uti backgroundFillColor:(UIColor*)fillColor 71 | { 72 | if (!path) 73 | return NO; 74 | 75 | NSURL* url = [[NSURL alloc] initFileURLWithPath:path]; 76 | const BOOL ret = [self saveToURL:url uti:uti backgroundFillColor:fillColor]; 77 | return ret; 78 | } 79 | 80 | -(BOOL)saveToPath:(NSString*)path type:(NYXImageType)type backgroundFillColor:(UIColor*)fillColor 81 | { 82 | if (!path) 83 | return NO; 84 | 85 | NSURL* url = [[NSURL alloc] initFileURLWithPath:path]; 86 | const BOOL ret = [self saveToURL:url uti:[self utiForType:type] backgroundFillColor:fillColor]; 87 | return ret; 88 | } 89 | 90 | -(BOOL)saveToPath:(NSString*)path 91 | { 92 | if (!path) 93 | return NO; 94 | 95 | NSURL* url = [[NSURL alloc] initFileURLWithPath:path]; 96 | const BOOL ret = [self saveToURL:url type:NYXImageTypePNG backgroundFillColor:nil]; 97 | return ret; 98 | } 99 | 100 | -(BOOL)saveToPhotosAlbum 101 | { 102 | ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 103 | __block BOOL ret = YES; 104 | [library writeImageToSavedPhotosAlbum:self.CGImage orientation:(ALAssetOrientation)self.imageOrientation completionBlock:^(NSURL* assetURL, NSError* error) { 105 | if (!assetURL) 106 | { 107 | NSLog(@"%@", error); 108 | ret = NO; 109 | } 110 | }]; 111 | return ret; 112 | } 113 | 114 | +(NSString*)extensionForUTI:(CFStringRef)uti 115 | { 116 | if (!uti) 117 | return nil; 118 | 119 | NSDictionary* declarations = (__bridge_transfer NSDictionary*)UTTypeCopyDeclaration(uti); 120 | if (!declarations) 121 | return nil; 122 | 123 | id extensions = [(NSDictionary*)[declarations objectForKey:(__bridge NSString*)kUTTypeTagSpecificationKey] objectForKey:(__bridge NSString*)kUTTagClassFilenameExtension]; 124 | NSString* extension = ([extensions isKindOfClass:[NSArray class]]) ? [extensions objectAtIndex:0] : extensions; 125 | 126 | return extension; 127 | } 128 | 129 | #pragma mark - Private 130 | -(CFStringRef)utiForType:(NYXImageType)type 131 | { 132 | CFStringRef uti = NULL; 133 | switch (type) 134 | { 135 | case NYXImageTypeBMP: 136 | uti = kUTTypeBMP; 137 | break; 138 | case NYXImageTypeJPEG: 139 | uti = kUTTypeJPEG; 140 | break; 141 | case NYXImageTypePNG: 142 | uti = kUTTypePNG; 143 | break; 144 | case NYXImageTypeTIFF: 145 | uti = kUTTypeTIFF; 146 | break; 147 | case NYXImageTypeGIF: 148 | uti = kUTTypeGIF; 149 | break; 150 | default: 151 | uti = kUTTypePNG; 152 | break; 153 | } 154 | return uti; 155 | } 156 | 157 | @end 158 | -------------------------------------------------------------------------------- /Categories/UIScrollView+Screenshot.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Screenshot.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 29/03/13. 6 | // Copyright 2013 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | @interface UIScrollView (NYX_Screenshot) 12 | 13 | -(UIImage*)imageByRenderingCurrentVisibleRect; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Categories/UIScrollView+Screenshot.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+Screenshot.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 29/03/13. 6 | // Copyright 2013 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIScrollView+Screenshot.h" 12 | #import 13 | 14 | @implementation UIScrollView (NYX_Screenshot) 15 | 16 | -(UIImage*)imageByRenderingCurrentVisibleRect 17 | { 18 | UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0.0f); 19 | CGContextRef context = UIGraphicsGetCurrentContext(); 20 | CGContextTranslateCTM(context, 0.0f, -self.contentOffset.y); 21 | [self.layer renderInContext:context]; 22 | UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); 23 | UIGraphicsEndImageContext(); 24 | return image; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Categories/UIView+Screenshot.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Screenshot.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 29/03/13. 6 | // Copyright 2013 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | @interface UIView (NYX_Screenshot) 12 | 13 | -(UIImage*)imageByRenderingView; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Categories/UIView+Screenshot.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Screenshot.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 29/03/13. 6 | // Copyright 2013 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIView+Screenshot.h" 12 | #import 13 | 14 | @implementation UIView (NYX_Screenshot) 15 | 16 | -(UIImage*)imageByRenderingView 17 | { 18 | UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0.0f); 19 | [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 20 | UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); 21 | UIGraphicsEndImageContext(); 22 | return image; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Classes/NYXProgressiveImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // NYXProgressiveImageView.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 13/01/12. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // Caching stuff by raphaelp 9 | // 10 | 11 | 12 | @protocol NYXProgressiveImageViewDelegate 13 | @optional 14 | -(void)imageDidLoadWithImage:(UIImage*)img; 15 | -(void)imageDownloadCompletedWithImage:(UIImage*)img; 16 | -(void)imageDownloadFailedWithData:(NSData*)data; 17 | @end 18 | 19 | 20 | @interface NYXProgressiveImageView : UIImageView 21 | 22 | #pragma mark - Public messages 23 | /// Launch the image download 24 | -(void)loadImageAtURL:(NSURL*)url; 25 | /// This will remove all cached images managed by any NYXProgressiveImageView instances 26 | +(void)resetImageCache; 27 | 28 | #pragma mark - Public properties 29 | /// Delegate 30 | @property (nonatomic, weak) IBOutlet id delegate; 31 | /// Enable / Disable caching 32 | @property (nonatomic, getter = isCaching) BOOL caching; 33 | /// Cache time in seconds 34 | @property (nonatomic) NSTimeInterval cacheTime; 35 | /// Downloading flag 36 | @property (nonatomic, readonly, getter = isDownloading) BOOL downloading; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Classes/NYXProgressiveImageView.m: -------------------------------------------------------------------------------- 1 | // 2 | // NYXProgressiveImageView.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 13/01/12. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // Caching stuff by raphaelp 9 | // 10 | 11 | 12 | #import "NYXProgressiveImageView.h" 13 | #import "NYXImagesHelper.h" 14 | //#import "UIImage+Saving.h" 15 | #import 16 | #import 17 | 18 | 19 | #define kNyxDefaultCacheTimeValue 604800.0f // 7 days 20 | #define kNyxDefaultTimeoutValue 10.0f 21 | 22 | 23 | typedef struct 24 | { 25 | unsigned int delegateImageDidLoadWithImage:1; 26 | unsigned int delegateImageDownloadCompletedWithImage:1; 27 | unsigned int delegateImageDownloadFailedWithData:1; 28 | } NyxDelegateFlags; 29 | 30 | 31 | @interface NYXProgressiveImageView() 32 | -(void)initializeAttributes; 33 | -(CGImageRef)createTransitoryImage:(CGImageRef)partialImage CF_RETURNS_RETAINED; 34 | +(NSString*)cacheDirectoryAddress; 35 | -(NSString*)cachedImageSystemName; 36 | -(void)resetCache; 37 | +(UIImageOrientation)exifOrientationToiOSOrientation:(int)exifOrientation; 38 | @end 39 | 40 | 41 | @implementation NYXProgressiveImageView 42 | { 43 | /// Image download connection 44 | NSURLConnection* _connection; 45 | /// Downloaded data 46 | NSMutableData* _dataTemp; 47 | /// Image source for progressive display 48 | CGImageSourceRef _imageSource; 49 | /// Width of the downloaded image 50 | int _imageWidth; 51 | /// Height of the downloaded image 52 | int _imageHeight; 53 | /// Expected image size 54 | long long _expectedSize; 55 | /// Image orientation 56 | UIImageOrientation _imageOrientation; 57 | /// Connection queue 58 | dispatch_queue_t _queue; 59 | /// Url 60 | NSURL* _url; 61 | /// Delegate flags, avoid to many respondsToSelector 62 | NyxDelegateFlags _delegateFlags; 63 | } 64 | 65 | @synthesize delegate = _delegate; 66 | @synthesize caching = _caching; 67 | @synthesize cacheTime = _cacheTime; 68 | @synthesize downloading = _downloading; 69 | 70 | #pragma mark - Allocations / Deallocations 71 | -(id)init 72 | { 73 | if ((self = [super init])) 74 | { 75 | [self initializeAttributes]; 76 | } 77 | return self; 78 | } 79 | 80 | -(id)initWithCoder:(NSCoder*)aDecoder 81 | { 82 | if ((self = [super initWithCoder:aDecoder])) 83 | { 84 | [self initializeAttributes]; 85 | } 86 | return self; 87 | } 88 | 89 | -(id)initWithFrame:(CGRect)frame 90 | { 91 | if ((self = [super initWithFrame:frame])) 92 | { 93 | [self initializeAttributes]; 94 | } 95 | return self; 96 | } 97 | 98 | -(id)initWithImage:(UIImage*)image 99 | { 100 | if ((self = [super initWithImage:image])) 101 | { 102 | [self initializeAttributes]; 103 | } 104 | return self; 105 | } 106 | 107 | -(id)initWithImage:(UIImage*)image highlightedImage:(UIImage*)highlightedImage 108 | { 109 | if ((self = [super initWithImage:image highlightedImage:highlightedImage])) 110 | { 111 | [self initializeAttributes]; 112 | } 113 | return self; 114 | } 115 | 116 | -(void)dealloc 117 | { 118 | NYX_DISPATCH_RELEASE(_queue); 119 | _queue = NULL; 120 | } 121 | 122 | #pragma mark - Public 123 | -(void)setDelegate:(id)delegate 124 | { 125 | if (delegate != _delegate) 126 | { 127 | _delegate = delegate; 128 | _delegateFlags.delegateImageDidLoadWithImage = (unsigned)[delegate respondsToSelector:@selector(imageDidLoadWithImage:)]; 129 | _delegateFlags.delegateImageDownloadCompletedWithImage = (unsigned)[delegate respondsToSelector:@selector(imageDownloadCompletedWithImage:)]; 130 | _delegateFlags.delegateImageDownloadFailedWithData = (unsigned)[delegate respondsToSelector:@selector(imageDownloadFailedWithData:)]; 131 | } 132 | } 133 | 134 | -(void)loadImageAtURL:(NSURL*)url 135 | { 136 | if (_downloading) 137 | return; 138 | 139 | _url = url; 140 | 141 | if (_caching) 142 | { 143 | NSFileManager* fileManager = [[NSFileManager alloc] init]; 144 | 145 | // check if file exists on cache 146 | NSString* cacheDir = [NYXProgressiveImageView cacheDirectoryAddress]; 147 | NSString* cachedImagePath = [cacheDir stringByAppendingPathComponent:[self cachedImageSystemName]]; 148 | if ([fileManager fileExistsAtPath:cachedImagePath]) 149 | { 150 | NSDate* mofificationDate = [[fileManager attributesOfItemAtPath:cachedImagePath error:nil] objectForKey:NSFileModificationDate]; 151 | 152 | // check modification date 153 | if (-[mofificationDate timeIntervalSinceNow] > _cacheTime) 154 | { 155 | // Removes old cache file... 156 | [self resetCache]; 157 | } 158 | else 159 | { 160 | // Loads image from cache without networking 161 | UIImage* localImage = [[UIImage alloc] initWithContentsOfFile:cachedImagePath]; 162 | dispatch_async(dispatch_get_main_queue(), ^{ 163 | self.image = localImage; 164 | 165 | if (_delegateFlags.delegateImageDidLoadWithImage) 166 | [_delegate imageDidLoadWithImage:localImage]; 167 | }); 168 | 169 | return; 170 | } 171 | } 172 | } 173 | 174 | dispatch_async(_queue, ^{ 175 | NSURLRequest* request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:kNyxDefaultTimeoutValue]; 176 | _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; 177 | [_connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 178 | _downloading = YES; 179 | [_connection start]; 180 | CFRunLoopRun(); 181 | }); 182 | } 183 | 184 | +(void)resetImageCache 185 | { 186 | [[NSFileManager defaultManager] removeItemAtPath:[NYXProgressiveImageView cacheDirectoryAddress] error:nil]; 187 | } 188 | 189 | #pragma mark - NSURLConnectionDelegate 190 | -(void)connection:(__unused NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response 191 | { 192 | _imageSource = CGImageSourceCreateIncremental(NULL); 193 | _imageWidth = _imageHeight = -1; 194 | _expectedSize = [response expectedContentLength]; 195 | _dataTemp = [[NSMutableData alloc] init]; 196 | } 197 | 198 | -(void)connection:(__unused NSURLConnection*)connection didReceiveData:(NSData*)data 199 | { 200 | [_dataTemp appendData:data]; 201 | 202 | const long long len = (long long)[_dataTemp length]; 203 | CGImageSourceUpdateData(_imageSource, (__bridge CFDataRef)_dataTemp, (len == _expectedSize) ? true : false); 204 | 205 | if (_imageHeight > 0 && _imageWidth > 0) 206 | { 207 | CGImageRef cgImage = CGImageSourceCreateImageAtIndex(_imageSource, 0, NULL); 208 | if (cgImage) 209 | { 210 | //if (NYX_IOS_VERSION_LESS_THAN(@"5.0")) 211 | //{ 212 | /// iOS 4.x fix to correctly handle JPEG images ( http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/ ) 213 | /// If the image doesn't have a transparency layer, the background is black-filled 214 | /// So we still need to render the image, it's teh sux. 215 | /// Note: Progressive JPEG are not supported see #32 216 | CGImageRef imgTmp = [self createTransitoryImage:cgImage]; 217 | if (imgTmp) 218 | { 219 | __block UIImage* img = [[UIImage alloc] initWithCGImage:imgTmp scale:1.0f orientation:_imageOrientation]; 220 | CGImageRelease(imgTmp); 221 | 222 | dispatch_async(dispatch_get_main_queue(), ^{ 223 | self.image = img; 224 | }); 225 | } 226 | //} 227 | //else 228 | //{ 229 | //__block UIImage* img = [[UIImage alloc] initWithCGImage:cgImage]; 230 | //dispatch_async(dispatch_get_main_queue(), ^{ 231 | //self.image = img; 232 | //}); 233 | //} 234 | CGImageRelease(cgImage); 235 | } 236 | } 237 | else 238 | { 239 | CFDictionaryRef dic = CGImageSourceCopyPropertiesAtIndex(_imageSource, 0, NULL); 240 | if (dic) 241 | { 242 | CFTypeRef val = CFDictionaryGetValue(dic, kCGImagePropertyPixelHeight); 243 | if (val) 244 | CFNumberGetValue(val, kCFNumberIntType, &_imageHeight); 245 | val = CFDictionaryGetValue(dic, kCGImagePropertyPixelWidth); 246 | if (val) 247 | CFNumberGetValue(val, kCFNumberIntType, &_imageWidth); 248 | 249 | val = CFDictionaryGetValue(dic, kCGImagePropertyOrientation); 250 | if (val) 251 | { 252 | int orientation; // Note: This is an EXIF int for orientation, a number between 1 and 8 253 | CFNumberGetValue(val, kCFNumberIntType, &orientation); 254 | _imageOrientation = [NYXProgressiveImageView exifOrientationToiOSOrientation:orientation]; 255 | } 256 | else 257 | _imageOrientation = UIImageOrientationUp; 258 | CFRelease(dic); 259 | } 260 | } 261 | } 262 | 263 | -(void)connectionDidFinishLoading:(__unused NSURLConnection*)connection 264 | { 265 | if (_dataTemp) 266 | { 267 | UIImage* img = [[UIImage alloc] initWithData:_dataTemp]; 268 | 269 | dispatch_sync(dispatch_get_main_queue(), ^{ 270 | if (_delegateFlags.delegateImageDownloadCompletedWithImage) 271 | [_delegate imageDownloadCompletedWithImage:img]; 272 | 273 | self.image = img; 274 | 275 | if (_delegateFlags.delegateImageDidLoadWithImage) 276 | [_delegate imageDidLoadWithImage:img]; 277 | }); 278 | 279 | if (_caching) 280 | { 281 | // Create cache directory if it doesn't exist 282 | BOOL isDir = YES; 283 | 284 | NSFileManager* fileManager = [[NSFileManager alloc] init]; 285 | 286 | NSString* cacheDir = [NYXProgressiveImageView cacheDirectoryAddress]; 287 | if (![fileManager fileExistsAtPath:cacheDir isDirectory:&isDir]) 288 | [fileManager createDirectoryAtPath:cacheDir withIntermediateDirectories:NO attributes:nil error:nil]; 289 | 290 | NSString* path = [cacheDir stringByAppendingPathComponent:[self cachedImageSystemName]]; 291 | //[img saveToPath:path uti:CGImageSourceGetType(_imageSource) backgroundFillColor:nil]; 292 | [_dataTemp writeToFile:path options:NSDataWritingAtomic error:nil]; 293 | } 294 | 295 | _dataTemp = nil; 296 | } 297 | 298 | if (_imageSource) 299 | { 300 | CFRelease(_imageSource); 301 | _imageSource = NULL; 302 | } 303 | _connection = nil; 304 | _url = nil; 305 | _downloading = NO; 306 | CFRunLoopStop(CFRunLoopGetCurrent()); 307 | } 308 | 309 | -(void)connection:(__unused NSURLConnection*)connection didFailWithError:(__unused NSError*)error 310 | { 311 | if (_delegateFlags.delegateImageDownloadFailedWithData) 312 | { 313 | dispatch_sync(dispatch_get_main_queue(), ^{ 314 | [_delegate imageDownloadFailedWithData:_dataTemp]; 315 | }); 316 | } 317 | 318 | _dataTemp = nil; 319 | if (_imageSource) 320 | { 321 | CFRelease(_imageSource); 322 | _imageSource = NULL; 323 | } 324 | _connection = nil; 325 | _url = nil; 326 | _downloading = NO; 327 | CFRunLoopStop(CFRunLoopGetCurrent()); 328 | } 329 | 330 | #pragma mark - Private 331 | -(void)initializeAttributes 332 | { 333 | _cacheTime = kNyxDefaultCacheTimeValue; 334 | _caching = NO; 335 | _queue = dispatch_queue_create("com.cits.pdlqueue", DISPATCH_QUEUE_SERIAL); 336 | _imageOrientation = UIImageOrientationUp; 337 | _imageSource = NULL; 338 | _dataTemp = nil; 339 | } 340 | 341 | -(CGImageRef)createTransitoryImage:(CGImageRef)partialImage 342 | { 343 | const size_t partialHeight = CGImageGetHeight(partialImage); 344 | CGContextRef bmContext = NYXCreateARGBBitmapContext((size_t)_imageWidth, (size_t)_imageHeight, (size_t)_imageWidth * 4, NYXImageHasAlpha(partialImage)); 345 | if (!bmContext) 346 | return NULL; 347 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = _imageWidth, .size.height = partialHeight}, partialImage); 348 | CGImageRef goodImageRef = CGBitmapContextCreateImage(bmContext); 349 | CGContextRelease(bmContext); 350 | return goodImageRef; 351 | } 352 | 353 | +(NSString*)cacheDirectoryAddress 354 | { 355 | NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 356 | NSString* documentsDirectoryPath = [paths objectAtIndex:0]; 357 | return [documentsDirectoryPath stringByAppendingPathComponent:@"NYXProgressiveImageViewCache"]; 358 | } 359 | 360 | -(NSString*)cachedImageSystemName 361 | { 362 | const char* concat_str = [[_url absoluteString] UTF8String]; 363 | if (!concat_str) 364 | return @""; 365 | 366 | unsigned char result[CC_MD5_DIGEST_LENGTH]; 367 | CC_MD5(concat_str, (CC_LONG)strlen(concat_str), result); 368 | 369 | NSMutableString* hash = [[NSMutableString alloc] init]; 370 | for (unsigned int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) 371 | [hash appendFormat:@"%02X", result[i]]; 372 | 373 | return [hash lowercaseString]; 374 | } 375 | 376 | -(void)resetCache 377 | { 378 | [[[NSFileManager alloc] init] removeItemAtPath:[[NYXProgressiveImageView cacheDirectoryAddress] stringByAppendingPathComponent:[self cachedImageSystemName]] error:nil]; 379 | } 380 | 381 | +(UIImageOrientation)exifOrientationToiOSOrientation:(int)exifOrientation 382 | { 383 | UIImageOrientation orientation = UIImageOrientationUp; 384 | switch (exifOrientation) 385 | { 386 | case 1: 387 | orientation = UIImageOrientationUp; 388 | break; 389 | case 3: 390 | orientation = UIImageOrientationDown; 391 | break; 392 | case 8: 393 | orientation = UIImageOrientationLeft; 394 | break; 395 | case 6: 396 | orientation = UIImageOrientationRight; 397 | break; 398 | case 2: 399 | orientation = UIImageOrientationUpMirrored; 400 | break; 401 | case 4: 402 | orientation = UIImageOrientationDownMirrored; 403 | break; 404 | case 5: 405 | orientation = UIImageOrientationLeftMirrored; 406 | break; 407 | case 7: 408 | orientation = UIImageOrientationRightMirrored; 409 | break; 410 | default: 411 | break; 412 | } 413 | return orientation; 414 | } 415 | 416 | @end 417 | -------------------------------------------------------------------------------- /Helper/NYXImagesHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // NYXImagesHelper.h 3 | // NYXImagesKit 4 | // 5 | // Created by Matthias Tretter on 02/06/11. 6 | // Originally Created by @Nyx0uf on 02/05/11. 7 | // Copyright 2012 Nyx0uf. All rights reserved. 8 | // www.cocoaintheshell.com 9 | // 10 | 11 | 12 | /* Number of components for an opaque grey colorSpace = 3 */ 13 | #define kNyxNumberOfComponentsPerGreyPixel 3 14 | /* Number of components for an ARGB pixel (Alpha / Red / Green / Blue) = 4 */ 15 | #define kNyxNumberOfComponentsPerARBGPixel 4 16 | /* Minimun value for a pixel component */ 17 | #define kNyxMinPixelComponentValue (UInt8)0 18 | /* Maximum value for a pixel component */ 19 | #define kNyxMaxPixelComponentValue (UInt8)255 20 | 21 | /* Convert degrees value to radians */ 22 | #define NYX_DEGREES_TO_RADIANS(__DEGREES) (__DEGREES * 0.017453293) // (M_PI / 180.0f) 23 | /* Convert radians value to degrees */ 24 | #define NYX_RADIANS_TO_DEGREES(__RADIANS) (__RADIANS * 57.295779513) // (180.0f / M_PI) 25 | 26 | /* Returns the lower value */ 27 | #define NYX_MIN(__A, __B) ((__A) < (__B) ? (__A) : (__B)) 28 | /* Returns the higher value */ 29 | #define NYX_MAX(__A ,__B) ((__A) > (__B) ? (__A) : (__B)) 30 | /* Returns a correct value for a pixel component (0 - 255) */ 31 | #define NYX_SAFE_PIXEL_COMPONENT_VALUE(__COLOR) (NYX_MIN(kNyxMaxPixelComponentValue, NYX_MAX(kNyxMinPixelComponentValue, __COLOR))) 32 | 33 | /* iOS version runtime check */ 34 | #define NYX_IOS_VERSION_LESS_THAN(__VERSIONSTRING) ([[[UIDevice currentDevice] systemVersion] compare:__VERSIONSTRING options:NSNumericSearch] == NSOrderedAscending) 35 | 36 | /* dispatch_release() not needed in iOS 6+ original idea from FMDB https://github.com/ccgus/fmdb/commit/aef763eeb64e6fa654e7d121f1df4c16a98d9f4f */ 37 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 38 | #define NYX_DISPATCH_RELEASE(__QUEUE) 39 | #else 40 | #define NYX_DISPATCH_RELEASE(__QUEUE) (dispatch_release(__QUEUE)) 41 | #endif 42 | 43 | CGContextRef NYXCreateARGBBitmapContext(const size_t width, const size_t height, const size_t bytesPerRow, BOOL withAlpha); 44 | CGImageRef NYXCreateGradientImage(const size_t pixelsWide, const size_t pixelsHigh, const CGFloat fromAlpha, const CGFloat toAlpha); 45 | CIContext* NYXGetCIContext(void); 46 | CGColorSpaceRef NYXGetRGBColorSpace(void); 47 | void NYXImagesKitRelease(void); 48 | BOOL NYXImageHasAlpha(CGImageRef imageRef); 49 | -------------------------------------------------------------------------------- /Helper/NYXImagesHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // NYXImagesHelper.m 3 | // NYXImagesKit 4 | // 5 | // Created by Matthias Tretter on 02/06/11. 6 | // Originally Created by @Nyx0uf on 02/05/11. 7 | // Copyright 2012 Nyx0uf. All rights reserved. 8 | // www.cocoaintheshell.com 9 | // 10 | 11 | 12 | #import "NYXImagesHelper.h" 13 | 14 | 15 | static CIContext* __ciContext = nil; 16 | static CGColorSpaceRef __rgbColorSpace = NULL; 17 | 18 | 19 | CGContextRef NYXCreateARGBBitmapContext(const size_t width, const size_t height, const size_t bytesPerRow, BOOL withAlpha) 20 | { 21 | /// Use the generic RGB color space 22 | /// We avoid the NULL check because CGColorSpaceRelease() NULL check the value anyway, and worst case scenario = fail to create context 23 | /// Create the bitmap context, we want pre-multiplied ARGB, 8-bits per component 24 | CGImageAlphaInfo alphaInfo = (withAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst); 25 | CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8/*Bits per component*/, bytesPerRow, NYXGetRGBColorSpace(), kCGBitmapByteOrderDefault | alphaInfo); 26 | 27 | return bmContext; 28 | } 29 | 30 | // The following function was taken from the increadibly awesome HockeyKit 31 | // Created by Peter Steinberger on 10.01.11. 32 | // Copyright 2012 Peter Steinberger. All rights reserved. 33 | CGImageRef NYXCreateGradientImage(const size_t pixelsWide, const size_t pixelsHigh, const CGFloat fromAlpha, const CGFloat toAlpha) 34 | { 35 | // gradient is always black-white and the mask must be in the gray colorspace 36 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 37 | 38 | // create the bitmap context 39 | CGContextRef gradientBitmapContext = CGBitmapContextCreate(NULL, pixelsWide, pixelsHigh, 8, 0, colorSpace, (CGBitmapInfo)kCGImageAlphaNone); 40 | 41 | // define the start and end grayscale values (with the alpha, even though 42 | // our bitmap context doesn't support alpha the gradient requires it) 43 | CGFloat colors[] = {toAlpha, 1.0f, fromAlpha, 1.0f}; 44 | 45 | // create the CGGradient and then release the gray color space 46 | CGGradientRef grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2); 47 | CGColorSpaceRelease(colorSpace); 48 | 49 | // create the start and end points for the gradient vector (straight down) 50 | CGPoint gradientEndPoint = CGPointZero; 51 | CGPoint gradientStartPoint = (CGPoint){.x = 0.0f, .y = pixelsHigh}; 52 | 53 | // draw the gradient into the gray bitmap context 54 | CGContextDrawLinearGradient(gradientBitmapContext, grayScaleGradient, gradientStartPoint, gradientEndPoint, kCGGradientDrawsAfterEndLocation); 55 | CGGradientRelease(grayScaleGradient); 56 | 57 | // convert the context into a CGImageRef and release the context 58 | CGImageRef theCGImage = CGBitmapContextCreateImage(gradientBitmapContext); 59 | CGContextRelease(gradientBitmapContext); 60 | 61 | // return the imageref containing the gradient 62 | return theCGImage; 63 | } 64 | 65 | CIContext* NYXGetCIContext(void) 66 | { 67 | if (!__ciContext) 68 | { 69 | NSNumber* num = [[NSNumber alloc] initWithBool:NO]; 70 | NSDictionary* opts = [[NSDictionary alloc] initWithObjectsAndKeys:num, kCIContextUseSoftwareRenderer, nil]; 71 | __ciContext = [CIContext contextWithOptions:opts]; 72 | } 73 | return __ciContext; 74 | } 75 | 76 | CGColorSpaceRef NYXGetRGBColorSpace(void) 77 | { 78 | if (!__rgbColorSpace) 79 | { 80 | __rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 81 | } 82 | return __rgbColorSpace; 83 | } 84 | 85 | void NYXImagesKitRelease(void) 86 | { 87 | if (__rgbColorSpace) 88 | CGColorSpaceRelease(__rgbColorSpace), __rgbColorSpace = NULL; 89 | if (__ciContext) 90 | __ciContext = nil; 91 | } 92 | 93 | BOOL NYXImageHasAlpha(CGImageRef imageRef) 94 | { 95 | CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef); 96 | BOOL hasAlpha = (alpha == kCGImageAlphaFirst || alpha == kCGImageAlphaLast || alpha == kCGImageAlphaPremultipliedFirst || alpha == kCGImageAlphaPremultipliedLast); 97 | 98 | return hasAlpha; 99 | } 100 | -------------------------------------------------------------------------------- /Helper/NYXImagesKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // NYXImagesKit.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | #import 11 | 12 | #import "UIImage+Blurring.h" 13 | #import "UIImage+Enhancing.h" 14 | #import "UIImage+Filtering.h" 15 | #import "UIImage+Masking.h" 16 | #import "UIImage+Reflection.h" 17 | #import "UIImage+Resizing.h" 18 | #import "UIImage+Rotating.h" 19 | #import "UIImage+Saving.h" 20 | #import "UIView+Screenshot.h" 21 | #import "UIScrollView+Screenshot.h" 22 | #import "NYXProgressiveImageView.h" 23 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2011 Benjamin Godard. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are 4 | permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of 7 | conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 10 | of conditions and the following disclaimer in the documentation and/or other materials 11 | provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY BENJAMIN GODARD ``AS IS'' AND ANY EXPRESS OR IMPLIED 14 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 15 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BENJAMIN GODARD OR 16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 20 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 21 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | 23 | The views and conclusions contained in the software and documentation are those of the 24 | authors and should not be interpreted as representing official policies, either expressed 25 | or implied, of Benjamin Godard. -------------------------------------------------------------------------------- /NYXImagesKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'NYXImagesKit' 3 | s.version = '2.4' 4 | s.platform = :ios 5 | s.license = 'Simplified BSD license' 6 | s.summary = 'A set of efficient categories for UIImage class. It allows filtering, resizing, masking, rotating, enhancing... and more.' 7 | s.homepage = 'https://github.com/Nyx0uf/NYXImagesKit' 8 | s.author = 'Benjamin Godard' 9 | s.source = { :git => 'https://github.com/Nyx0uf/NYXImagesKit.git', :tag => '2.4' } 10 | s.source_files = 'Categories', 'Classes', 'Helper' 11 | s.frameworks = 'Accelerate', 'AssetsLibrary', 'ImageIO', 'MobileCoreServices', 'QuartzCore', 'CoreImage' 12 | s.platform = :ios, '5.1' 13 | s.requires_arc = true 14 | end 15 | -------------------------------------------------------------------------------- /NYXImagesKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1E0289DB144EF32200B6B6D5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E0289DA144EF32200B6B6D5 /* Foundation.framework */; }; 11 | 1E0289ED144EF38B00B6B6D5 /* Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 1E0289EC144EF38B00B6B6D5 /* Prefix.pch */; }; 12 | 1E028A01144EF39800B6B6D5 /* UIImage+Blurring.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E0289EF144EF39800B6B6D5 /* UIImage+Blurring.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 1E028A02144EF39800B6B6D5 /* UIImage+Blurring.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E0289F0144EF39800B6B6D5 /* UIImage+Blurring.m */; }; 14 | 1E028A03144EF39800B6B6D5 /* UIImage+Filtering.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E0289F1144EF39800B6B6D5 /* UIImage+Filtering.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 1E028A04144EF39800B6B6D5 /* UIImage+Filtering.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E0289F2144EF39800B6B6D5 /* UIImage+Filtering.m */; }; 16 | 1E028A05144EF39800B6B6D5 /* UIImage+Masking.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E0289F3144EF39800B6B6D5 /* UIImage+Masking.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | 1E028A06144EF39800B6B6D5 /* UIImage+Masking.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E0289F4144EF39800B6B6D5 /* UIImage+Masking.m */; }; 18 | 1E028A07144EF39800B6B6D5 /* UIImage+Reflection.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E0289F5144EF39800B6B6D5 /* UIImage+Reflection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 1E028A08144EF39800B6B6D5 /* UIImage+Reflection.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E0289F6144EF39800B6B6D5 /* UIImage+Reflection.m */; }; 20 | 1E028A09144EF39800B6B6D5 /* UIImage+Resizing.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E0289F7144EF39800B6B6D5 /* UIImage+Resizing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | 1E028A0A144EF39800B6B6D5 /* UIImage+Resizing.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E0289F8144EF39800B6B6D5 /* UIImage+Resizing.m */; }; 22 | 1E028A0B144EF39800B6B6D5 /* UIImage+Rotating.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E0289F9144EF39800B6B6D5 /* UIImage+Rotating.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | 1E028A0C144EF39800B6B6D5 /* UIImage+Rotating.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E0289FA144EF39800B6B6D5 /* UIImage+Rotating.m */; }; 24 | 1E028A0D144EF39800B6B6D5 /* UIImage+Saving.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E0289FB144EF39800B6B6D5 /* UIImage+Saving.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25 | 1E028A0E144EF39800B6B6D5 /* UIImage+Saving.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E0289FC144EF39800B6B6D5 /* UIImage+Saving.m */; }; 26 | 1E028A0F144EF39800B6B6D5 /* NYXImagesHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E0289FE144EF39800B6B6D5 /* NYXImagesHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; 27 | 1E028A10144EF39800B6B6D5 /* NYXImagesHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E0289FF144EF39800B6B6D5 /* NYXImagesHelper.m */; }; 28 | 1E028A11144EF39800B6B6D5 /* NYXImagesKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E028A00144EF39800B6B6D5 /* NYXImagesKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | 1E028A13144EF3AA00B6B6D5 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E028A12144EF3AA00B6B6D5 /* QuartzCore.framework */; }; 30 | 1E028A15144EF3AF00B6B6D5 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E028A14144EF3AF00B6B6D5 /* ImageIO.framework */; }; 31 | 1E028A17144EF3B500B6B6D5 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E028A16144EF3B500B6B6D5 /* MobileCoreServices.framework */; }; 32 | 1E028A19144EF41000B6B6D5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E028A18144EF41000B6B6D5 /* UIKit.framework */; }; 33 | 1E30CA89148E57CB00106BF8 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E30CA88148E57CA00106BF8 /* Accelerate.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 34 | 1E53F0E41486C3FF00BD33AD /* CoreImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E53F0E31486C3FF00BD33AD /* CoreImage.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 35 | 1E9BA7B314C0B0EF0072A0FB /* NYXProgressiveImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E9BA7B114C0B0EF0072A0FB /* NYXProgressiveImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 36 | 1E9BA7B414C0B0EF0072A0FB /* NYXProgressiveImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E9BA7B214C0B0EF0072A0FB /* NYXProgressiveImageView.m */; }; 37 | 1EED6787148A314B00B71186 /* UIImage+Enhancing.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EED6785148A314B00B71186 /* UIImage+Enhancing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 38 | 1EED6788148A314B00B71186 /* UIImage+Enhancing.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EED6786148A314B00B71186 /* UIImage+Enhancing.m */; }; 39 | 1EF44D4F17058586005F335C /* UIView+Screenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EF44D4D17058586005F335C /* UIView+Screenshot.h */; }; 40 | 1EF44D5017058586005F335C /* UIView+Screenshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EF44D4E17058586005F335C /* UIView+Screenshot.m */; }; 41 | 1EF44D5317058627005F335C /* UIScrollView+Screenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EF44D5117058627005F335C /* UIScrollView+Screenshot.h */; }; 42 | 1EF44D5417058627005F335C /* UIScrollView+Screenshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EF44D5217058627005F335C /* UIScrollView+Screenshot.m */; }; 43 | /* End PBXBuildFile section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 1E0289D7144EF32200B6B6D5 /* libNYXImagesKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNYXImagesKit.a; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 1E0289DA144EF32200B6B6D5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 48 | 1E0289EC144EF38B00B6B6D5 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Prefix.pch; path = "Other Sources/Prefix.pch"; sourceTree = ""; }; 49 | 1E0289EF144EF39800B6B6D5 /* UIImage+Blurring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Blurring.h"; sourceTree = ""; }; 50 | 1E0289F0144EF39800B6B6D5 /* UIImage+Blurring.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Blurring.m"; sourceTree = ""; }; 51 | 1E0289F1144EF39800B6B6D5 /* UIImage+Filtering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Filtering.h"; sourceTree = ""; }; 52 | 1E0289F2144EF39800B6B6D5 /* UIImage+Filtering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Filtering.m"; sourceTree = ""; }; 53 | 1E0289F3144EF39800B6B6D5 /* UIImage+Masking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Masking.h"; sourceTree = ""; }; 54 | 1E0289F4144EF39800B6B6D5 /* UIImage+Masking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Masking.m"; sourceTree = ""; }; 55 | 1E0289F5144EF39800B6B6D5 /* UIImage+Reflection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Reflection.h"; sourceTree = ""; }; 56 | 1E0289F6144EF39800B6B6D5 /* UIImage+Reflection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Reflection.m"; sourceTree = ""; }; 57 | 1E0289F7144EF39800B6B6D5 /* UIImage+Resizing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Resizing.h"; sourceTree = ""; }; 58 | 1E0289F8144EF39800B6B6D5 /* UIImage+Resizing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Resizing.m"; sourceTree = ""; }; 59 | 1E0289F9144EF39800B6B6D5 /* UIImage+Rotating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Rotating.h"; sourceTree = ""; }; 60 | 1E0289FA144EF39800B6B6D5 /* UIImage+Rotating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Rotating.m"; sourceTree = ""; }; 61 | 1E0289FB144EF39800B6B6D5 /* UIImage+Saving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Saving.h"; sourceTree = ""; }; 62 | 1E0289FC144EF39800B6B6D5 /* UIImage+Saving.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Saving.m"; sourceTree = ""; }; 63 | 1E0289FE144EF39800B6B6D5 /* NYXImagesHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NYXImagesHelper.h; sourceTree = ""; }; 64 | 1E0289FF144EF39800B6B6D5 /* NYXImagesHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NYXImagesHelper.m; sourceTree = ""; }; 65 | 1E028A00144EF39800B6B6D5 /* NYXImagesKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NYXImagesKit.h; sourceTree = ""; }; 66 | 1E028A12144EF3AA00B6B6D5 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 67 | 1E028A14144EF3AF00B6B6D5 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; }; 68 | 1E028A16144EF3B500B6B6D5 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; 69 | 1E028A18144EF41000B6B6D5 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 70 | 1E30CA88148E57CA00106BF8 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; 71 | 1E53F0E31486C3FF00BD33AD /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; }; 72 | 1E9BA7B114C0B0EF0072A0FB /* NYXProgressiveImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NYXProgressiveImageView.h; sourceTree = ""; }; 73 | 1E9BA7B214C0B0EF0072A0FB /* NYXProgressiveImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NYXProgressiveImageView.m; sourceTree = ""; }; 74 | 1EED6785148A314B00B71186 /* UIImage+Enhancing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Enhancing.h"; sourceTree = ""; }; 75 | 1EED6786148A314B00B71186 /* UIImage+Enhancing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Enhancing.m"; sourceTree = ""; }; 76 | 1EF44D4D17058586005F335C /* UIView+Screenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Screenshot.h"; sourceTree = ""; }; 77 | 1EF44D4E17058586005F335C /* UIView+Screenshot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Screenshot.m"; sourceTree = ""; }; 78 | 1EF44D5117058627005F335C /* UIScrollView+Screenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+Screenshot.h"; sourceTree = ""; }; 79 | 1EF44D5217058627005F335C /* UIScrollView+Screenshot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+Screenshot.m"; sourceTree = ""; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | 1E0289D4144EF32200B6B6D5 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | 1E30CA89148E57CB00106BF8 /* Accelerate.framework in Frameworks */, 88 | 1E53F0E41486C3FF00BD33AD /* CoreImage.framework in Frameworks */, 89 | 1E028A19144EF41000B6B6D5 /* UIKit.framework in Frameworks */, 90 | 1E028A17144EF3B500B6B6D5 /* MobileCoreServices.framework in Frameworks */, 91 | 1E028A15144EF3AF00B6B6D5 /* ImageIO.framework in Frameworks */, 92 | 1E028A13144EF3AA00B6B6D5 /* QuartzCore.framework in Frameworks */, 93 | 1E0289DB144EF32200B6B6D5 /* Foundation.framework in Frameworks */, 94 | ); 95 | runOnlyForDeploymentPostprocessing = 0; 96 | }; 97 | /* End PBXFrameworksBuildPhase section */ 98 | 99 | /* Begin PBXGroup section */ 100 | 1E0289CC144EF32200B6B6D5 = { 101 | isa = PBXGroup; 102 | children = ( 103 | 1E0289FD144EF39800B6B6D5 /* Helper */, 104 | 1E9BA7B014C0B0EF0072A0FB /* Classes */, 105 | 1E0289EE144EF39800B6B6D5 /* Categories */, 106 | 1E0289EB144EF37F00B6B6D5 /* Other Sources */, 107 | 1E0289D9144EF32200B6B6D5 /* Frameworks */, 108 | 1E0289D8144EF32200B6B6D5 /* Products */, 109 | ); 110 | sourceTree = ""; 111 | }; 112 | 1E0289D8144EF32200B6B6D5 /* Products */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 1E0289D7144EF32200B6B6D5 /* libNYXImagesKit.a */, 116 | ); 117 | name = Products; 118 | sourceTree = ""; 119 | }; 120 | 1E0289D9144EF32200B6B6D5 /* Frameworks */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 1E30CA88148E57CA00106BF8 /* Accelerate.framework */, 124 | 1E53F0E31486C3FF00BD33AD /* CoreImage.framework */, 125 | 1E028A18144EF41000B6B6D5 /* UIKit.framework */, 126 | 1E028A16144EF3B500B6B6D5 /* MobileCoreServices.framework */, 127 | 1E028A14144EF3AF00B6B6D5 /* ImageIO.framework */, 128 | 1E028A12144EF3AA00B6B6D5 /* QuartzCore.framework */, 129 | 1E0289DA144EF32200B6B6D5 /* Foundation.framework */, 130 | ); 131 | name = Frameworks; 132 | sourceTree = ""; 133 | }; 134 | 1E0289EB144EF37F00B6B6D5 /* Other Sources */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 1E0289EC144EF38B00B6B6D5 /* Prefix.pch */, 138 | ); 139 | name = "Other Sources"; 140 | sourceTree = ""; 141 | }; 142 | 1E0289EE144EF39800B6B6D5 /* Categories */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 1E0289EF144EF39800B6B6D5 /* UIImage+Blurring.h */, 146 | 1E0289F0144EF39800B6B6D5 /* UIImage+Blurring.m */, 147 | 1EED6785148A314B00B71186 /* UIImage+Enhancing.h */, 148 | 1EED6786148A314B00B71186 /* UIImage+Enhancing.m */, 149 | 1E0289F1144EF39800B6B6D5 /* UIImage+Filtering.h */, 150 | 1E0289F2144EF39800B6B6D5 /* UIImage+Filtering.m */, 151 | 1E0289F3144EF39800B6B6D5 /* UIImage+Masking.h */, 152 | 1E0289F4144EF39800B6B6D5 /* UIImage+Masking.m */, 153 | 1E0289F5144EF39800B6B6D5 /* UIImage+Reflection.h */, 154 | 1E0289F6144EF39800B6B6D5 /* UIImage+Reflection.m */, 155 | 1E0289F7144EF39800B6B6D5 /* UIImage+Resizing.h */, 156 | 1E0289F8144EF39800B6B6D5 /* UIImage+Resizing.m */, 157 | 1E0289F9144EF39800B6B6D5 /* UIImage+Rotating.h */, 158 | 1E0289FA144EF39800B6B6D5 /* UIImage+Rotating.m */, 159 | 1E0289FB144EF39800B6B6D5 /* UIImage+Saving.h */, 160 | 1E0289FC144EF39800B6B6D5 /* UIImage+Saving.m */, 161 | 1EF44D4D17058586005F335C /* UIView+Screenshot.h */, 162 | 1EF44D4E17058586005F335C /* UIView+Screenshot.m */, 163 | 1EF44D5117058627005F335C /* UIScrollView+Screenshot.h */, 164 | 1EF44D5217058627005F335C /* UIScrollView+Screenshot.m */, 165 | ); 166 | path = Categories; 167 | sourceTree = ""; 168 | }; 169 | 1E0289FD144EF39800B6B6D5 /* Helper */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 1E0289FE144EF39800B6B6D5 /* NYXImagesHelper.h */, 173 | 1E0289FF144EF39800B6B6D5 /* NYXImagesHelper.m */, 174 | 1E028A00144EF39800B6B6D5 /* NYXImagesKit.h */, 175 | ); 176 | path = Helper; 177 | sourceTree = ""; 178 | }; 179 | 1E9BA7B014C0B0EF0072A0FB /* Classes */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 1E9BA7B114C0B0EF0072A0FB /* NYXProgressiveImageView.h */, 183 | 1E9BA7B214C0B0EF0072A0FB /* NYXProgressiveImageView.m */, 184 | ); 185 | path = Classes; 186 | sourceTree = ""; 187 | }; 188 | /* End PBXGroup section */ 189 | 190 | /* Begin PBXHeadersBuildPhase section */ 191 | 1E0289D5144EF32200B6B6D5 /* Headers */ = { 192 | isa = PBXHeadersBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | 1E028A11144EF39800B6B6D5 /* NYXImagesKit.h in Headers */, 196 | 1E028A01144EF39800B6B6D5 /* UIImage+Blurring.h in Headers */, 197 | 1E028A03144EF39800B6B6D5 /* UIImage+Filtering.h in Headers */, 198 | 1E028A05144EF39800B6B6D5 /* UIImage+Masking.h in Headers */, 199 | 1E028A07144EF39800B6B6D5 /* UIImage+Reflection.h in Headers */, 200 | 1E028A09144EF39800B6B6D5 /* UIImage+Resizing.h in Headers */, 201 | 1E028A0B144EF39800B6B6D5 /* UIImage+Rotating.h in Headers */, 202 | 1E028A0D144EF39800B6B6D5 /* UIImage+Saving.h in Headers */, 203 | 1EED6787148A314B00B71186 /* UIImage+Enhancing.h in Headers */, 204 | 1E9BA7B314C0B0EF0072A0FB /* NYXProgressiveImageView.h in Headers */, 205 | 1E028A0F144EF39800B6B6D5 /* NYXImagesHelper.h in Headers */, 206 | 1E0289ED144EF38B00B6B6D5 /* Prefix.pch in Headers */, 207 | 1EF44D4F17058586005F335C /* UIView+Screenshot.h in Headers */, 208 | 1EF44D5317058627005F335C /* UIScrollView+Screenshot.h in Headers */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXHeadersBuildPhase section */ 213 | 214 | /* Begin PBXNativeTarget section */ 215 | 1E0289D6144EF32200B6B6D5 /* NYXImagesKit */ = { 216 | isa = PBXNativeTarget; 217 | buildConfigurationList = 1E0289E4144EF32200B6B6D5 /* Build configuration list for PBXNativeTarget "NYXImagesKit" */; 218 | buildPhases = ( 219 | 1E0289D3144EF32200B6B6D5 /* Sources */, 220 | 1E0289D4144EF32200B6B6D5 /* Frameworks */, 221 | 1E0289D5144EF32200B6B6D5 /* Headers */, 222 | ); 223 | buildRules = ( 224 | ); 225 | dependencies = ( 226 | ); 227 | name = NYXImagesKit; 228 | productName = NYXImagesUtilities; 229 | productReference = 1E0289D7144EF32200B6B6D5 /* libNYXImagesKit.a */; 230 | productType = "com.apple.product-type.library.static"; 231 | }; 232 | /* End PBXNativeTarget section */ 233 | 234 | /* Begin PBXProject section */ 235 | 1E0289CE144EF32200B6B6D5 /* Project object */ = { 236 | isa = PBXProject; 237 | attributes = { 238 | LastUpgradeCheck = 0500; 239 | ORGANIZATIONNAME = MacGeneration; 240 | }; 241 | buildConfigurationList = 1E0289D1144EF32200B6B6D5 /* Build configuration list for PBXProject "NYXImagesKit" */; 242 | compatibilityVersion = "Xcode 3.2"; 243 | developmentRegion = English; 244 | hasScannedForEncodings = 0; 245 | knownRegions = ( 246 | en, 247 | ); 248 | mainGroup = 1E0289CC144EF32200B6B6D5; 249 | productRefGroup = 1E0289D8144EF32200B6B6D5 /* Products */; 250 | projectDirPath = ""; 251 | projectRoot = ""; 252 | targets = ( 253 | 1E0289D6144EF32200B6B6D5 /* NYXImagesKit */, 254 | ); 255 | }; 256 | /* End PBXProject section */ 257 | 258 | /* Begin PBXSourcesBuildPhase section */ 259 | 1E0289D3144EF32200B6B6D5 /* Sources */ = { 260 | isa = PBXSourcesBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | 1E028A02144EF39800B6B6D5 /* UIImage+Blurring.m in Sources */, 264 | 1E028A04144EF39800B6B6D5 /* UIImage+Filtering.m in Sources */, 265 | 1E028A06144EF39800B6B6D5 /* UIImage+Masking.m in Sources */, 266 | 1E028A08144EF39800B6B6D5 /* UIImage+Reflection.m in Sources */, 267 | 1E028A0A144EF39800B6B6D5 /* UIImage+Resizing.m in Sources */, 268 | 1E028A0C144EF39800B6B6D5 /* UIImage+Rotating.m in Sources */, 269 | 1E028A0E144EF39800B6B6D5 /* UIImage+Saving.m in Sources */, 270 | 1E028A10144EF39800B6B6D5 /* NYXImagesHelper.m in Sources */, 271 | 1EED6788148A314B00B71186 /* UIImage+Enhancing.m in Sources */, 272 | 1E9BA7B414C0B0EF0072A0FB /* NYXProgressiveImageView.m in Sources */, 273 | 1EF44D5017058586005F335C /* UIView+Screenshot.m in Sources */, 274 | 1EF44D5417058627005F335C /* UIScrollView+Screenshot.m in Sources */, 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | /* End PBXSourcesBuildPhase section */ 279 | 280 | /* Begin XCBuildConfiguration section */ 281 | 1E0289E2144EF32200B6B6D5 /* Debug */ = { 282 | isa = XCBuildConfiguration; 283 | buildSettings = { 284 | ALWAYS_SEARCH_USER_PATHS = NO; 285 | CLANG_ENABLE_OBJC_ARC = YES; 286 | CLANG_WARN_CONSTANT_CONVERSION = YES; 287 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 288 | CLANG_WARN_EMPTY_BODY = YES; 289 | CLANG_WARN_ENUM_CONVERSION = YES; 290 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; 291 | CLANG_WARN_INT_CONVERSION = YES; 292 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; 293 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 294 | COPY_PHASE_STRIP = NO; 295 | GCC_C_LANGUAGE_STANDARD = gnu99; 296 | GCC_DYNAMIC_NO_PIC = NO; 297 | GCC_OPTIMIZATION_LEVEL = 0; 298 | GCC_PREPROCESSOR_DEFINITIONS = ( 299 | "DEBUG=1", 300 | "$(inherited)", 301 | ); 302 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 303 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 304 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; 305 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 306 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 307 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 308 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 309 | GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; 310 | GCC_WARN_SHADOW = YES; 311 | GCC_WARN_SIGN_COMPARE = YES; 312 | GCC_WARN_UNDECLARED_SELECTOR = YES; 313 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 314 | GCC_WARN_UNKNOWN_PRAGMAS = YES; 315 | GCC_WARN_UNUSED_FUNCTION = YES; 316 | GCC_WARN_UNUSED_LABEL = YES; 317 | GCC_WARN_UNUSED_PARAMETER = YES; 318 | GCC_WARN_UNUSED_VARIABLE = YES; 319 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 320 | ONLY_ACTIVE_ARCH = YES; 321 | SDKROOT = iphoneos; 322 | }; 323 | name = Debug; 324 | }; 325 | 1E0289E3144EF32200B6B6D5 /* Release */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | ALWAYS_SEARCH_USER_PATHS = NO; 329 | CLANG_ENABLE_OBJC_ARC = YES; 330 | CLANG_WARN_CONSTANT_CONVERSION = YES; 331 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 332 | CLANG_WARN_EMPTY_BODY = YES; 333 | CLANG_WARN_ENUM_CONVERSION = YES; 334 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; 335 | CLANG_WARN_INT_CONVERSION = YES; 336 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; 337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 338 | COPY_PHASE_STRIP = YES; 339 | GCC_C_LANGUAGE_STANDARD = gnu99; 340 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 341 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; 342 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 343 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 345 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 346 | GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; 347 | GCC_WARN_SHADOW = YES; 348 | GCC_WARN_SIGN_COMPARE = YES; 349 | GCC_WARN_UNDECLARED_SELECTOR = YES; 350 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 351 | GCC_WARN_UNKNOWN_PRAGMAS = YES; 352 | GCC_WARN_UNUSED_FUNCTION = YES; 353 | GCC_WARN_UNUSED_LABEL = YES; 354 | GCC_WARN_UNUSED_PARAMETER = YES; 355 | GCC_WARN_UNUSED_VARIABLE = YES; 356 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 357 | SDKROOT = iphoneos; 358 | VALIDATE_PRODUCT = YES; 359 | }; 360 | name = Release; 361 | }; 362 | 1E0289E5144EF32200B6B6D5 /* Debug */ = { 363 | isa = XCBuildConfiguration; 364 | buildSettings = { 365 | CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; 366 | CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES; 367 | CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES; 368 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 369 | CLANG_WARN_EMPTY_BODY = YES; 370 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; 371 | CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; 372 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; 373 | DSTROOT = /tmp/NYXImagesUtilities.dst; 374 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 375 | GCC_PREFIX_HEADER = "Other Sources/Prefix.pch"; 376 | GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; 377 | GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; 378 | GCC_TREAT_WARNINGS_AS_ERRORS = YES; 379 | GCC_VERSION = ""; 380 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 381 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; 382 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 383 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; 384 | GCC_WARN_INHIBIT_ALL_WARNINGS = NO; 385 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 386 | GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; 387 | GCC_WARN_PEDANTIC = YES; 388 | GCC_WARN_SHADOW = YES; 389 | GCC_WARN_SIGN_COMPARE = YES; 390 | GCC_WARN_STRICT_SELECTOR_MATCH = YES; 391 | GCC_WARN_UNDECLARED_SELECTOR = YES; 392 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 393 | GCC_WARN_UNKNOWN_PRAGMAS = YES; 394 | GCC_WARN_UNUSED_FUNCTION = YES; 395 | GCC_WARN_UNUSED_LABEL = YES; 396 | GCC_WARN_UNUSED_PARAMETER = YES; 397 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 398 | OTHER_LDFLAGS = "-ObjC"; 399 | PRODUCT_NAME = NYXImagesKit; 400 | PUBLIC_HEADERS_FOLDER_PATH = "include/$(TARGET_NAME)"; 401 | RUN_CLANG_STATIC_ANALYZER = YES; 402 | SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; 403 | SKIP_INSTALL = YES; 404 | }; 405 | name = Debug; 406 | }; 407 | 1E0289E6144EF32200B6B6D5 /* Release */ = { 408 | isa = XCBuildConfiguration; 409 | buildSettings = { 410 | CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; 411 | CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES; 412 | CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES; 413 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 414 | CLANG_WARN_EMPTY_BODY = YES; 415 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; 416 | CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; 417 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; 418 | DSTROOT = /tmp/NYXImagesUtilities.dst; 419 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 420 | GCC_PREFIX_HEADER = "Other Sources/Prefix.pch"; 421 | GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; 422 | GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; 423 | GCC_TREAT_WARNINGS_AS_ERRORS = YES; 424 | GCC_VERSION = ""; 425 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 426 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; 427 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 428 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; 429 | GCC_WARN_INHIBIT_ALL_WARNINGS = NO; 430 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 431 | GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; 432 | GCC_WARN_PEDANTIC = YES; 433 | GCC_WARN_SHADOW = YES; 434 | GCC_WARN_SIGN_COMPARE = YES; 435 | GCC_WARN_STRICT_SELECTOR_MATCH = YES; 436 | GCC_WARN_UNDECLARED_SELECTOR = YES; 437 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 438 | GCC_WARN_UNKNOWN_PRAGMAS = YES; 439 | GCC_WARN_UNUSED_FUNCTION = YES; 440 | GCC_WARN_UNUSED_LABEL = YES; 441 | GCC_WARN_UNUSED_PARAMETER = YES; 442 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 443 | OTHER_LDFLAGS = "-ObjC"; 444 | PRODUCT_NAME = NYXImagesKit; 445 | PUBLIC_HEADERS_FOLDER_PATH = "include/$(TARGET_NAME)"; 446 | RUN_CLANG_STATIC_ANALYZER = YES; 447 | SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; 448 | SKIP_INSTALL = YES; 449 | }; 450 | name = Release; 451 | }; 452 | /* End XCBuildConfiguration section */ 453 | 454 | /* Begin XCConfigurationList section */ 455 | 1E0289D1144EF32200B6B6D5 /* Build configuration list for PBXProject "NYXImagesKit" */ = { 456 | isa = XCConfigurationList; 457 | buildConfigurations = ( 458 | 1E0289E2144EF32200B6B6D5 /* Debug */, 459 | 1E0289E3144EF32200B6B6D5 /* Release */, 460 | ); 461 | defaultConfigurationIsVisible = 0; 462 | defaultConfigurationName = Release; 463 | }; 464 | 1E0289E4144EF32200B6B6D5 /* Build configuration list for PBXNativeTarget "NYXImagesKit" */ = { 465 | isa = XCConfigurationList; 466 | buildConfigurations = ( 467 | 1E0289E5144EF32200B6B6D5 /* Debug */, 468 | 1E0289E6144EF32200B6B6D5 /* Release */, 469 | ); 470 | defaultConfigurationIsVisible = 0; 471 | defaultConfigurationName = Release; 472 | }; 473 | /* End XCConfigurationList section */ 474 | }; 475 | rootObject = 1E0289CE144EF32200B6B6D5 /* Project object */; 476 | } 477 | -------------------------------------------------------------------------------- /NYXImagesKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NYXImagesKit.xcodeproj/project.xcworkspace/xcuserdata/Nyxouf.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /NYXImagesKit.xcodeproj/xcuserdata/Nyxouf.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /NYXImagesKit.xcodeproj/xcuserdata/Nyxouf.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | NYXImagesUtilities.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 1E0289D6144EF32200B6B6D5 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Other Sources/Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix.pch 3 | // NYXImagesKit 4 | // 5 | // Created by Nyx0uf on 5/2/11. 6 | // Copyright 2011 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #import 15 | #endif 16 | 17 | #if !__has_feature(objc_arc) 18 | #error This file must be compiled with ARC. 19 | #endif 20 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # This project is not maintained anymore # 2 | 3 | # NYXImagesKit # 4 | 5 | This is a project for iOS which regroups a collection of useful *UIImage* categories to handle operations such as filtering, blurring, enhancing, masking, reflecting, resizing, rotating, saving. There is also a subclass of *UIImageView* to load an image asynchronously from a URL and display it as it is downloaded. 6 | 7 | It requires at least *iOS 5.1*. 8 | 9 | ***NYXImagesKit*** is designed to be very efficient, **vDSP** is used when possible, some filters use **Core Image** or **vImage** to be as fast as possible. 10 | 11 | The project is a static library so that you don't have to import the sources in your own project and build them each time. 12 | 13 | 14 | ### ARC Support ### 15 | 16 | ***NYXImagesKit*** fully supports **ARC** out of the box, there is no configuration necessary. Also, as it is a library you can use it without problems in a **non-ARC** project. 17 | 18 | 19 | ### Installation ### 20 | 21 | First open the **NYXImagesKit.xcodeproj** and build the library, then import the library and the headers in your project, and finally link with these frameworks : 22 | 23 | - **Accelerate** 24 | - **AssetsLibrary** 25 | - **ImageIO** 26 | - **MobileCoreServices** 27 | - **QuartzCore** 28 | - **CoreImage** 29 | 30 | Or if you want, you can add the sources to your project and build them along. 31 | 32 | ### UIImage+Filtering ### 33 | 34 | This category allows you to apply filters on a *UIImage* object, currently there are 11 filters : 35 | 36 | 1. Brighten 37 | 2. Contrast adjustment 38 | 3. Edge detection 39 | 4. Emboss 40 | 5. Gamma correction 41 | 6. Grayscale 42 | 7. Invert 43 | 8. Opacity 44 | 9. Sepia 45 | 10. Sharpen 46 | 11. Unsharpen 47 | 48 | 49 | ### UIImage+Blurring ### 50 | 51 | This category is composed of a single method to blur an *UIImage*. Blurring is done using is done using **vImage**. 52 | 53 | [myImage gaussianBlurWithBias:0]; 54 | 55 | 56 | ### UIImage+Masking ### 57 | 58 | This category is composed of a single method which allows to mask an image with another image, you just have to create the mask image you desire. 59 | 60 | UIImage* masked = [myImage maskWithImage:[UIImage imageNamed:@"mask.png"]]; 61 | 62 | 63 | ### UIImage+Resizing ### 64 | 65 | This category can be used to crop or to scale images. 66 | 67 | 68 | #### Cropping #### 69 | 70 | You can crop your image by 9 different ways : 71 | 72 | 1. Top left 73 | 2. Top center 74 | 3. Top right 75 | 4. Bottom left 76 | 5. Bottom center 77 | 6. Bottom right 78 | 7. Left center 79 | 8. Right center 80 | 9. Center 81 | 82 | 83 | UIImage* cropped = [myImage cropToSize:(CGSize){width, height} usingMode:NYXCropModeCenter]; 84 | 85 | NYXCropMode is an enum type which can be found in the header file, it is used to represent the 9 modes above. 86 | 87 | 88 | #### Scaling #### 89 | 90 | You have the choice between two methods to scale images, the two methods will keep the aspect ratio of the original image. 91 | 92 | UIImage* scaled1 = [myImage scaleByFactor:0.5f]; 93 | UIImage* scaled2 = [myImage scaleToFitSize:(CGSize){width, height}]; 94 | 95 | 96 | ### UIImage+Rotating ### 97 | 98 | With this category you can rotate or flip an *UIImage*, flipping is useful if you want to create a reflect effect. 99 | 100 | UIImage* rotated1 = [myImage rotateInDegrees:217.0f]; 101 | UIImage* rotated2 = [myImage rotateInRadians:M_PI_2]; 102 | UIImage* flipped1 = [myImage verticalFlip]; 103 | UIImage* flipped2 = [myImage horizontalFlip]; 104 | 105 | 106 | ### UIImage+Reflection ### 107 | 108 | This category was written by Matthias Tretter (@myell0w) and is composed of a single method to create a reflected image. 109 | 110 | UIImage* reflected = [myImage reflectedImageWithHeight:myImage.size.height fromAlpha:0.0f toAlpha:0.5f]; 111 | 112 | 113 | ### UIImage+Enhancing ### 114 | 115 | This category works only on *iOS 5* because it uses **Core Image**, it allows to enhance an image or to perform red eye correction. 116 | 117 | [myImage autoEnhance]; 118 | [myImage redEyeCorrection]; 119 | 120 | 121 | ### UIImage+Saving ### 122 | 123 | This category allows you to save an *UIImage* at a specified path or file URL or to your Photos album, there are five types supported : 124 | 125 | 1. BMP 126 | 2. GIF 127 | 3. JPG 128 | 4. PNG 129 | 5. TIFF 130 | 131 | To use it, you must link with **ImageIO.framework**, **MobileCoreServices.framework** and **AssetsLibrary.framework**. 132 | 133 | [myImage saveToURL:url type:NYXImageTypeJPEG backgroundFillColor:nil]; 134 | [myImage saveToPath:path type:NYXImageTypeTIFF backgroundFillColor:[UIColor yellowColor]]; 135 | [myImage saveToPhotosAlbum]; 136 | 137 | There is also two other methods which take only the path or URL as parameter and save the image in PNG, because it's the preferred format for iOS. 138 | 139 | If your image contains transparent zone and you save it in a format that doesn't support alpha, a fill color will be used, if you don't specify one, the default color will be white. 140 | 141 | 142 | ### NYXProgressiveImageView ### 143 | 144 | This is a subclass of *UIImageView* to load asynchronously an image from an URL and display it as it is being downloaded. Image caching is supported. 145 | For more informations see and . 146 | 147 | 148 | ### License ### 149 | 150 | ***NYXImagesKit*** is released under the *Simplified BSD license*, see **LICENSE.txt**. 151 | --------------------------------------------------------------------------------