project_files/HedgewarsMobile/Classes/UIImageExtra.m
author koda
Wed, 23 Jun 2010 22:03:56 +0200
changeset 3547 02875b1145b7
parent 3546 ccf4854df294
child 3573 c84067629035
permissions -rw-r--r--
i <3 mercurial
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3547
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
     1
//
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
     2
//  UIImageExtra.m
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
     3
//  HedgewarsMobile
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
     4
//
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
     5
//  Created by Vittorio on 08/04/10.
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
     6
//  Copyright 2010 __MyCompanyName__. All rights reserved.
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
     7
//
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
     8
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
     9
#import "UIImageExtra.h"
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    10
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    11
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    12
@implementation UIImage (extra)
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    13
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    14
-(UIImage *)scaleToSize:(CGSize) size {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    15
  // Create a bitmap graphics context
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    16
  // This will also set it as the current context
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    17
  UIGraphicsBeginImageContext(size);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    18
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    19
  // Draw the scaled image in the current context
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    20
  [self drawInRect:CGRectMake(0, 0, size.width, size.height)];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    21
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    22
  // Create a new image from current context
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    23
  UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    24
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    25
  // Pop the current context from the stack
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    26
  UIGraphicsEndImageContext();
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    27
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    28
  // Return our new scaled image (autoreleased)
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    29
  return scaledImage;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    30
}
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    31
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    32
-(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    33
    // create a contex of size of the background image
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    34
    return [self mergeWith:secondImage atPoint:secondImagePoint atSize:self.size];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    35
}
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    36
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    37
-(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint atSize:(CGSize) resultingSize {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    38
    UIGraphicsBeginImageContext(resultingSize);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    39
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    40
    // drav the background image
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    41
    [self drawAtPoint:CGPointMake(0,0)];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    42
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    43
    // draw the image on top of the first image
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    44
    [secondImage drawAtPoint:secondImagePoint];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    45
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    46
    // create an image from the current contex (not thread safe)
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    47
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    48
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    49
    // free drawing contex
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    50
    UIGraphicsEndImageContext();
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    51
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    52
    // return the resulting autoreleased image
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    53
    return resultImage;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    54
}
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    55
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    56
-(id) initWithContentsOfFile:(NSString *)path andCutAt:(CGRect) rect {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    57
    // load image from path
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    58
    UIImage *image = [[UIImage alloc] initWithContentsOfFile: path];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    59
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    60
    if (nil != image) {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    61
        // get its CGImage representation with a give size
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    62
        CGImageRef cgImgage = CGImageCreateWithImageInRect([image CGImage], rect);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    63
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    64
        // clean memory
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    65
        [image release];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    66
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    67
        // create a UIImage from the CGImage (memory must be allocated already)
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    68
        UIImage *sprite = [self initWithCGImage:cgImgage];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    69
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    70
        // clean memory
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    71
        CGImageRelease(cgImgage);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    72
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    73
        // return resulting image
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    74
        return sprite;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    75
    } else {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    76
        DLog(@"error - image == nil");
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    77
        return nil;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    78
    }
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    79
}
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    80
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    81
-(UIImage *)convertToGrayScale {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    82
  // Create image rectangle with current image width/height
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    83
  CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    84
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    85
  // Grayscale color space
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    86
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    87
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    88
  // Create bitmap content with current image size and grayscale colorspace
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    89
  CGContextRef context = CGBitmapContextCreate(nil, self.size.width, self.size.height, 8, 0, colorSpace, kCGImageAlphaNone);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    90
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    91
  // Draw image into current context, with specified rectangle
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    92
  // using previously defined context (with grayscale colorspace)
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    93
  CGContextDrawImage(context, imageRect, [self CGImage]);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    94
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    95
  // Create bitmap image info from pixel data in current context
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    96
  CGImageRef imageRef = CGBitmapContextCreateImage(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    97
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    98
  // Create a new UIImage object  
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
    99
  UIImage *newImage = [UIImage imageWithCGImage:imageRef];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   100
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   101
  // Release colorspace, context and bitmap information
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   102
  CGColorSpaceRelease(colorSpace);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   103
  CGContextRelease(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   104
  CFRelease(imageRef);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   105
 
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   106
  // Return the new grayscale image
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   107
  return newImage;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   108
}
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   109
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   110
// by http://iphonedevelopertips.com/cocoa/how-to-mask-an-image.html turned into a category by koda
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   111
-(UIImage*) maskImageWith:(UIImage *)maskImage {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   112
    CGImageRef maskRef = maskImage.CGImage;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   113
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   114
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   115
                                        CGImageGetHeight(maskRef),
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   116
                                        CGImageGetBitsPerComponent(maskRef),
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   117
                                        CGImageGetBitsPerPixel(maskRef),
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   118
                                        CGImageGetBytesPerRow(maskRef),
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   119
                                        CGImageGetDataProvider(maskRef), NULL, false);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   120
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   121
    CGImageRef masked = CGImageCreateWithMask([self CGImage], mask);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   122
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   123
    CGImageRelease(mask);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   124
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   125
    UIImage* retImage = [UIImage imageWithCGImage:masked];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   126
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   127
    CGImageRelease(masked);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   128
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   129
    return retImage;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   130
}
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   131
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   132
// by http://blog.sallarp.com/iphone-uiimage-round-corners/ turned into a category by koda
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   133
void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight)
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   134
{
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   135
    float fw, fh;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   136
    if (ovalWidth == 0 || ovalHeight == 0) {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   137
        CGContextAddRect(context, rect);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   138
        return;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   139
    }
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   140
    CGContextSaveGState(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   141
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   142
    CGContextScaleCTM (context, ovalWidth, ovalHeight);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   143
    fw = CGRectGetWidth (rect) / ovalWidth;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   144
    fh = CGRectGetHeight (rect) / ovalHeight;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   145
    CGContextMoveToPoint(context, fw, fh/2);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   146
    CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   147
    CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   148
    CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   149
    CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   150
    CGContextClosePath(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   151
    CGContextRestoreGState(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   152
}
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   153
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   154
-(UIImage *)makeRoundCornersOfSize:(CGSize) sizewh {
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   155
    UIImage * newImage = nil;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   156
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   157
    NSInteger cornerWidth = sizewh.width;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   158
    NSInteger cornerHeight = sizewh.height;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   159
    int w = self.size.width;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   160
    int h = self.size.height;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   161
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   162
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   163
    CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   164
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   165
    CGContextBeginPath(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   166
    CGRect rect = CGRectMake(0, 0, w, h);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   167
    addRoundedRectToPath(context, rect, cornerWidth, cornerHeight);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   168
    CGContextClosePath(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   169
    CGContextClip(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   170
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   171
    CGContextDrawImage(context, CGRectMake(0, 0, w, h), self.CGImage);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   172
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   173
    CGImageRef imageMasked = CGBitmapContextCreateImage(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   174
    CGContextRelease(context);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   175
    CGColorSpaceRelease(colorSpace);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   176
    
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   177
    newImage = [UIImage imageWithCGImage:imageMasked];
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   178
    CGImageRelease(imageMasked);
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   179
        
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   180
    return newImage;
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   181
}
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   182
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   183
02875b1145b7 i <3 mercurial
koda
parents: 3546
diff changeset
   184
@end