Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
H2CO3 committed Aug 22, 2011
0 parents commit 8b26f33
Show file tree
Hide file tree
Showing 9 changed files with 712 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.txt
@@ -0,0 +1,5 @@
UIImage+Editor: useful category for quickly manipulating UIImages as in a simple image editor
Some hints, ideas and code was taken from StackOverflow and random web sites
The Alpha, Rounded Corner and Resize categories were written by Trevor Harmon.
Licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License. I am not responsible for any damage related to the use of the software. There is no warranty at all.

16 changes: 16 additions & 0 deletions UIImage+Alpha.h
@@ -0,0 +1,16 @@
// UIImage+Alpha.h
// Created by Trevor Harmon on 9/20/09.
// Free for personal or commercial use, with or without modification.
// No warranty is expressed or implied.

// Helper methods for adding an alpha layer to an image

#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIKit.h>

@interface UIImage (Alpha)
- (BOOL)hasAlpha;
- (UIImage *)imageWithAlpha;
- (UIImage *)transparentBorderImage:(NSUInteger)borderSize;
@end

127 changes: 127 additions & 0 deletions UIImage+Alpha.m
@@ -0,0 +1,127 @@
// UIImage+Alpha.m
// Created by Trevor Harmon on 9/20/09.
// Free for personal or commercial use, with or without modification.
// No warranty is expressed or implied.

#import "UIImage+Alpha.h"

// Private helper methods
@interface UIImage ()
- (CGImageRef)newBorderMask:(NSUInteger)borderSize size:(CGSize)size;
@end

@implementation UIImage (Alpha)

// Returns true if the image has an alpha layer
- (BOOL)hasAlpha {
CGImageAlphaInfo alpha = CGImageGetAlphaInfo(self.CGImage);
return (alpha == kCGImageAlphaFirst ||
alpha == kCGImageAlphaLast ||
alpha == kCGImageAlphaPremultipliedFirst ||
alpha == kCGImageAlphaPremultipliedLast);
}

// Returns a copy of the given image, adding an alpha channel if it doesn't already have one
- (UIImage *)imageWithAlpha {
if ([self hasAlpha]) {
return self;
}

CGImageRef imageRef = self.CGImage;
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);

// The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error
CGContextRef offscreenContext = CGBitmapContextCreate(NULL,
width,
height,
8,
0,
CGImageGetColorSpace(imageRef),
kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);

// Draw the image into the context and retrieve the new image, which will now have an alpha layer
CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), imageRef);
CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(offscreenContext);
UIImage *imageWithAlpha = [UIImage imageWithCGImage:imageRefWithAlpha];

// Clean up
CGContextRelease(offscreenContext);
CGImageRelease(imageRefWithAlpha);

return imageWithAlpha;
}

// Returns a copy of the image with a transparent border of the given size added around its edges.
// If the image has no alpha layer, one will be added to it.
- (UIImage *)transparentBorderImage:(NSUInteger)borderSize {
// If the image does not have an alpha layer, add one
UIImage *image = [self imageWithAlpha];

CGRect newRect = CGRectMake(0, 0, image.size.width + borderSize * 2, image.size.height + borderSize * 2);

// Build a context that's the same dimensions as the new size
CGContextRef bitmap = CGBitmapContextCreate(NULL,
newRect.size.width,
newRect.size.height,
CGImageGetBitsPerComponent(self.CGImage),
0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));

// Draw the image in the center of the context, leaving a gap around the edges
CGRect imageLocation = CGRectMake(borderSize, borderSize, image.size.width, image.size.height);
CGContextDrawImage(bitmap, imageLocation, self.CGImage);
CGImageRef borderImageRef = CGBitmapContextCreateImage(bitmap);

// Create a mask to make the border transparent, and combine it with the image
CGImageRef maskImageRef = [self newBorderMask:borderSize size:newRect.size];
CGImageRef transparentBorderImageRef = CGImageCreateWithMask(borderImageRef, maskImageRef);
UIImage *transparentBorderImage = [UIImage imageWithCGImage:transparentBorderImageRef];

// Clean up
CGContextRelease(bitmap);
CGImageRelease(borderImageRef);
CGImageRelease(maskImageRef);
CGImageRelease(transparentBorderImageRef);

return transparentBorderImage;
}

#pragma mark -
#pragma mark Private helper methods

// Creates a mask that makes the outer edges transparent and everything else opaque
// The size must include the entire mask (opaque part + transparent border)
// The caller is responsible for releasing the returned reference by calling CGImageRelease
- (CGImageRef)newBorderMask:(NSUInteger)borderSize size:(CGSize)size {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

// Build a context that's the same dimensions as the new size
CGContextRef maskContext = CGBitmapContextCreate(NULL,
size.width,
size.height,
8, // 8-bit grayscale
0,
colorSpace,
kCGBitmapByteOrderDefault | kCGImageAlphaNone);

// Start with a mask that's entirely transparent
CGContextSetFillColorWithColor(maskContext, [UIColor blackColor].CGColor);
CGContextFillRect(maskContext, CGRectMake(0, 0, size.width, size.height));

// Make the inner part (within the border) opaque
CGContextSetFillColorWithColor(maskContext, [UIColor whiteColor].CGColor);
CGContextFillRect(maskContext, CGRectMake(borderSize, borderSize, size.width - borderSize * 2, size.height - borderSize * 2));

// Get an image of the context
CGImageRef maskImageRef = CGBitmapContextCreateImage(maskContext);

// Clean up
CGContextRelease(maskContext);
CGColorSpaceRelease(colorSpace);

return maskImageRef;
}

@end
48 changes: 48 additions & 0 deletions UIImage+Editor.h
@@ -0,0 +1,48 @@
//
// UIImage+Editor.h
// Originally created for MyFile
//
// UIImage+Editor is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License.
// As attribution, I just require that you mention my name in conjunction
// with this library, and that your application can reproduce this legal notice.
// For details, see: http://creativecommons.org/licenses/
//
// Although this library was written in the hope that it will be useful,
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS', THUS
// THERE IS NO WARRANTY AT ALL, NEITHER EXPRESSED OR IMPLIED, NOT EVEN
// FOR MERCHANTABILITY OR FITTNESS FOR A PARTICUALR PURPOSE. I (THE AUTHOR) AM NOT RESPONSIBLE
// FOR ANY DAMAGE, DATA LOSS OR ANY OTHER TYPES OF UNEXPECTED AND/OR BAD RESULTS
// IN CONNECTION OF THIS SOFTWARE.
//
// Created by Árpád Goretity, 2011.
//

#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIKit.h>
#import "UIImage+Resize.h"
#import "UIImage+RoundedCorner.h"
#import "UIImage+Alpha.h"

CGFloat degreesToRadians (CGFloat degrees);
CGFloat radiansToDegrees (CGFloat radians);

@interface UIImage (Editor)

// resize to a specified (width, height) size. Can be used for stretching.
- (UIImage *) resizedToSize: (CGSize) size;
// resize to a specified ratio (ratio must not be 0)
- (UIImage *) resizedByRatio: (CGFloat) ratio;
// crop a specified rect from the middle of the image
- (UIImage *) croppedToRect: (CGRect) rect;
// generate a rounded corner image by adjusting the corner arcs' alpha
- (UIImage *) withBorderRadius: (CGFloat) radius;
// draw a string to the specified string at a given point, with a given font and color
- (UIImage *) addText: (NSString *) str atPoint: (CGPoint) point withFont: (UIFont *) font ofColor: (UIColor *) color;
// return a grayscale copy of the image
- (UIImage *) grayscaled;
// return a transparent copy of the image
- (UIImage *) withAlpha: (CGFloat) alpha;
// return a rotated copy of the image. Specify rotation angle in degrees. Use radiansToDegrees() to convert radians to degrees.
- (UIImage *) rotatedByDegrees: (CGFloat) degrees;
@end

0 comments on commit 8b26f33

Please sign in to comment.