22 #import "UIImageExtra.h" |
22 #import "UIImageExtra.h" |
23 |
23 |
24 |
24 |
25 @implementation UIImage (extra) |
25 @implementation UIImage (extra) |
26 |
26 |
27 CGFloat getScreenScale(void) { |
|
28 float scale = 1.0f; |
|
29 if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) |
|
30 scale = [[UIScreen mainScreen] scale]; |
|
31 return scale; |
|
32 } |
|
33 |
|
34 -(UIImage *)scaleToSize:(CGSize) size { |
27 -(UIImage *)scaleToSize:(CGSize) size { |
35 DLog(@"warning - this is a very expensive operation, you should avoid using it"); |
|
36 |
|
37 // Create a bitmap graphics context; this will also set it as the current context |
28 // Create a bitmap graphics context; this will also set it as the current context |
38 if (UIGraphicsBeginImageContextWithOptions != NULL) |
29 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
39 UIGraphicsBeginImageContextWithOptions(size, NO, getScreenScale()); |
30 CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 4 * size.width, colorSpace, kCGImageAlphaPremultipliedFirst); |
|
31 |
|
32 // draw the image inside the context |
|
33 CGFloat screenScale = [[UIScreen mainScreen] safeScale]; |
|
34 CGContextDrawImage(context, CGRectMake(0, 0, size.width*screenScale, size.height*screenScale), self.CGImage); |
|
35 |
|
36 // Create bitmap image info from pixel data in current context |
|
37 CGImageRef imageRef = CGBitmapContextCreateImage(context); |
|
38 |
|
39 // Create a new UIImage object |
|
40 UIImage *resultImage; |
|
41 if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) |
|
42 resultImage = [UIImage imageWithCGImage:imageRef scale:screenScale orientation:UIImageOrientationUp]; |
40 else |
43 else |
41 UIGraphicsBeginImageContext(size); |
44 resultImage = [UIImage imageWithCGImage:imageRef]; |
42 |
45 |
43 // Draw the scaled image in the current context |
46 // Release colorspace, context and bitmap information |
44 [self drawInRect:CGRectMake(0, 0, size.width, size.height)]; |
47 CGColorSpaceRelease(colorSpace); |
45 |
48 CGContextRelease(context); |
46 // Create a new image from current context |
49 CFRelease(imageRef); |
47 UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); |
50 |
48 |
51 return resultImage; |
49 // Pop the current context from the stack |
|
50 UIGraphicsEndImageContext(); |
|
51 |
|
52 // Return our new scaled image (autoreleased) |
|
53 return scaledImage; |
|
54 } |
52 } |
55 |
53 |
56 -(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint { |
54 -(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint { |
57 if (secondImage == nil) { |
55 if (secondImage == nil) { |
58 DLog(@"Warning, secondImage == nil"); |
56 DLog(@"Warning, secondImage == nil"); |
59 return self; |
57 return self; |
60 } |
58 } |
61 CGFloat screenScale = getScreenScale(); |
59 CGFloat screenScale = [[UIScreen mainScreen] safeScale]; |
62 int w = self.size.width * screenScale; |
60 int w = self.size.width * screenScale; |
63 int h = self.size.height * screenScale; |
61 int h = self.size.height * screenScale; |
64 |
62 int yOffset = self.size.height - secondImage.size.height + secondImagePoint.y; |
|
63 |
65 if (w == 0 || h == 0) { |
64 if (w == 0 || h == 0) { |
66 DLog(@"Can have 0 dimesions"); |
65 DLog(@"Cannot have 0 dimesions"); |
67 return self; |
66 return self; |
68 } |
67 } |
69 |
68 |
70 // Create a bitmap graphics context; this will also set it as the current context |
69 // Create a bitmap graphics context; this will also set it as the current context |
71 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
70 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
72 CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst); |
71 CGContextRef context = CGBitmapContextCreate(NULL, w, h+yOffset, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst); |
73 |
72 |
74 // draw the two images in the current context |
73 // draw the two images in the current context |
75 CGContextDrawImage(context, CGRectMake(0, 0, self.size.width*screenScale, self.size.height*screenScale), [self CGImage]); |
74 CGContextDrawImage(context, CGRectMake(0, 0, self.size.width*screenScale, self.size.height*screenScale), [self CGImage]); |
76 CGContextDrawImage(context, CGRectMake(secondImagePoint.x*screenScale, secondImagePoint.y*screenScale, secondImage.size.width*screenScale, secondImage.size.height*screenScale), [secondImage CGImage]); |
75 CGContextDrawImage(context, CGRectMake(secondImagePoint.x*screenScale, secondImagePoint.y*screenScale, secondImage.size.width*screenScale, secondImage.size.height*screenScale), [secondImage CGImage]); |
77 |
76 |
78 // Create bitmap image info from pixel data in current context |
77 // Create bitmap image info from pixel data in current context |
79 CGImageRef imageRef = CGBitmapContextCreateImage(context); |
78 CGImageRef imageRef = CGBitmapContextCreateImage(context); |
80 |
79 |
81 // Create a new UIImage object |
80 // Create a new UIImage object |
82 UIImage *resultImage; |
81 UIImage *resultImage; |
83 if ([self respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) |
82 if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) |
84 resultImage = [UIImage imageWithCGImage:imageRef scale:screenScale orientation:UIImageOrientationUp]; |
83 resultImage = [UIImage imageWithCGImage:imageRef scale:screenScale orientation:UIImageOrientationUp]; |
85 else |
84 else |
86 resultImage = [UIImage imageWithCGImage:imageRef]; |
85 resultImage = [UIImage imageWithCGImage:imageRef]; |
87 |
86 |
88 // Release colorspace, context and bitmap information |
87 // Release colorspace, context and bitmap information |
89 CGColorSpaceRelease(colorSpace); |
88 CGColorSpaceRelease(colorSpace); |
90 CGContextRelease(context); |
89 CGContextRelease(context); |
91 CFRelease(imageRef); |
90 CFRelease(imageRef); |
92 |
91 |
93 return resultImage; |
92 return resultImage; |
94 } |
93 } |
95 |
94 |
96 -(id) initWithContentsOfFile:(NSString *)path andCutAt:(CGRect) rect { |
95 -(id) initWithContentsOfFile:(NSString *)path andCutAt:(CGRect) rect { |
97 // load image from path |
96 // load image from path |
266 UIImage *bkgImg = [UIImage imageWithCGImage:image]; |
264 UIImage *bkgImg = [UIImage imageWithCGImage:image]; |
267 CGImageRelease(image); |
265 CGImageRelease(image); |
268 return bkgImg; |
266 return bkgImg; |
269 } |
267 } |
270 |
268 |
|
269 +(UIImage *)drawHogsRepeated:(NSInteger) manyTimes { |
|
270 NSString *imgString = [[NSString alloc] initWithFormat:@"%@/hedgehog.png",[[NSBundle mainBundle] resourcePath]]; |
|
271 UIImage *hogSprite = [[UIImage alloc] initWithContentsOfFile:imgString]; |
|
272 [imgString release]; |
|
273 CGFloat screenScale = [[UIScreen mainScreen] safeScale]; |
|
274 int w = hogSprite.size.width * screenScale; |
|
275 int h = hogSprite.size.height * screenScale; |
|
276 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
|
277 CGContextRef context = CGBitmapContextCreate(NULL, w * 3, h, 8, 4 * w * 3, colorSpace, kCGImageAlphaPremultipliedFirst); |
|
278 |
|
279 // draw the two images in the current context |
|
280 for (int i = 0; i < manyTimes; i++) |
|
281 CGContextDrawImage(context, CGRectMake(i*8*screenScale, 0, w, h), [hogSprite CGImage]); |
|
282 [hogSprite release]; |
|
283 |
|
284 // Create bitmap image info from pixel data in current context |
|
285 CGImageRef imageRef = CGBitmapContextCreateImage(context); |
|
286 |
|
287 // Create a new UIImage object |
|
288 UIImage *resultImage; |
|
289 if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) |
|
290 resultImage = [UIImage imageWithCGImage:imageRef scale:screenScale orientation:UIImageOrientationUp]; |
|
291 else |
|
292 resultImage = [UIImage imageWithCGImage:imageRef]; |
|
293 |
|
294 // Release colorspace, context and bitmap information |
|
295 CGColorSpaceRelease(colorSpace); |
|
296 CGContextRelease(context); |
|
297 CFRelease(imageRef); |
|
298 |
|
299 return resultImage; |
|
300 } |
|
301 |
|
302 // this routine checks for the PNG size without loading it in memory |
|
303 // https://github.com/steipete/PSFramework/blob/master/PSFramework%20Version%200.3/PhotoshopFramework/PSMetaDataFunctions.m |
|
304 +(CGSize) imageSizeFromMetadataOf:(NSString *)aFileName { |
|
305 // File Name to C String. |
|
306 const char *fileName = [aFileName UTF8String]; |
|
307 // source file |
|
308 FILE *infile = fopen(fileName, "rb"); |
|
309 if (infile == NULL) { |
|
310 DLog(@"Can't open the file: %@", aFileName); |
|
311 return CGSizeZero; |
|
312 } |
|
313 |
|
314 // Bytes Buffer. |
|
315 unsigned char buffer[30]; |
|
316 // Grab Only First Bytes. |
|
317 fread(buffer, 1, 30, infile); |
|
318 // Close File. |
|
319 fclose(infile); |
|
320 |
|
321 // PNG Signature. |
|
322 unsigned char png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; |
|
323 |
|
324 // Compare File signature. |
|
325 if ((int)(memcmp(&buffer[0], &png_signature[0], 8))) { |
|
326 DLog(@"The file (%@) is not a PNG file", aFileName); |
|
327 return CGSizeZero; |
|
328 } |
|
329 |
|
330 // Calc Sizes. Isolate only four bytes of each size (width, height). |
|
331 int width[4]; |
|
332 int height[4]; |
|
333 for (int d = 16; d < (16 + 4); d++) { |
|
334 width[d-16] = buffer[d]; |
|
335 height[d-16] = buffer[d+4]; |
|
336 } |
|
337 |
|
338 // Convert bytes to Long (Integer) |
|
339 long resultWidth = (width[0] << (int)24) | (width[1] << (int)16) | (width[2] << (int)8) | width[3]; |
|
340 long resultHeight = (height[0] << (int)24) | (height[1] << (int)16) | (height[2] << (int)8) | height[3]; |
|
341 |
|
342 // Return Size. |
|
343 return CGSizeMake(resultWidth,resultHeight); |
|
344 } |
|
345 |
271 @end |
346 @end |