project_files/HedgewarsMobile/Classes/UIImageExtra.m
branchhedgeroid
changeset 6224 42b256eca362
parent 6209 074ab6ebcb3e
child 6700 e04da46ee43c
equal deleted inserted replaced
6055:88cfcd9161d3 6224:42b256eca362
    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
   201 }
   200 }
   202 
   201 
   203 -(UIImage *)makeRoundCornersOfSize:(CGSize) sizewh {
   202 -(UIImage *)makeRoundCornersOfSize:(CGSize) sizewh {
   204     CGFloat cornerWidth = sizewh.width;
   203     CGFloat cornerWidth = sizewh.width;
   205     CGFloat cornerHeight = sizewh.height;
   204     CGFloat cornerHeight = sizewh.height;
   206     CGFloat screenScale = getScreenScale();
   205     CGFloat screenScale = [[UIScreen mainScreen] safeScale];
   207     CGFloat w = self.size.width * screenScale;
   206     CGFloat w = self.size.width * screenScale;
   208     CGFloat h = self.size.height * screenScale;
   207     CGFloat h = self.size.height * screenScale;
   209 
   208 
   210     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
   209     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
   211     CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
   210     CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
   220 
   219 
   221     CGImageRef imageMasked = CGBitmapContextCreateImage(context);
   220     CGImageRef imageMasked = CGBitmapContextCreateImage(context);
   222     CGContextRelease(context);
   221     CGContextRelease(context);
   223     CGColorSpaceRelease(colorSpace);
   222     CGColorSpaceRelease(colorSpace);
   224 
   223 
   225     UIImage *newImage;
   224     UIImage *resultImage;
   226     if ([self respondsToSelector:@selector(imageWithCGImage:scale:orientation:)])
   225     if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)])
   227         newImage = [UIImage imageWithCGImage:imageMasked scale:screenScale orientation:UIImageOrientationUp];
   226         resultImage = [UIImage imageWithCGImage:imageMasked scale:screenScale orientation:UIImageOrientationUp];
   228     else
   227     else
   229         newImage = [UIImage imageWithCGImage:imageMasked];
   228         resultImage = [UIImage imageWithCGImage:imageMasked];
   230 
       
   231     CGImageRelease(imageMasked);
   229     CGImageRelease(imageMasked);
   232 
   230 
   233     return newImage;
   231     return resultImage;
   234 }
   232 }
   235 
   233 
   236 // by http://www.sixtemia.com/journal/2010/06/23/uiimage-negative-color-effect/
   234 // by http://www.sixtemia.com/journal/2010/06/23/uiimage-negative-color-effect/
   237 -(UIImage *)convertToNegative {
   235 -(UIImage *)convertToNegative {
   238     UIGraphicsBeginImageContext(self.size);
   236     UIGraphicsBeginImageContext(self.size);
   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