Skip to content
This repository has been archived by the owner on Feb 27, 2018. It is now read-only.

Commit

Permalink
Add podspec, update README
Browse files Browse the repository at this point in the history
  • Loading branch information
gizmosachin committed Jan 12, 2015
1 parent 80f81f2 commit a387b2e
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 2 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ Category for trimming transparent pixels of an UIImage object.

How to use
----------
Add the `UIImage+Trim` files to your project. Include `UIImage+Trim.h` in the files where you want to trim your images.
Add `UIImage+Trim` to your project with Cocoapods:

`pod 'UIImage-Trim', :git => 'https://github.com/gizmosachin/UIImage-Trim'`

Include `UIImage+Trim.h` in the files where you want to trim your images.

Trimming is pretty straightforward:

Expand Down
1 change: 1 addition & 0 deletions UIImage+Trim.h → Source/UIImage+Trim.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
- (UIEdgeInsets)transparencyInsetsRequiringFullOpacity:(BOOL)fullyOpaque;
- (UIImage *)imageByTrimmingTransparentPixels;
- (UIImage *)imageByTrimmingTransparentPixelsRequiringFullOpacity:(BOOL)fullyOpaque;
- (UIImage *)imageByTrimmingWhitePixelsWithOpacity:(UInt8)tolerance;

@end
137 changes: 136 additions & 1 deletion UIImage+Trim.m → Source/UIImage+Trim.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ - (UIEdgeInsets)transparencyInsetsRequiringFullOpacity:(BOOL)fullyOpaque
uint8_t * bitmapData = calloc((size_t)(width * height), sizeof(uint8_t));

// Create alpha-only bitmap context
CGContextRef contextRef = CGBitmapContextCreate(bitmapData, (NSUInteger)width, (NSUInteger)height, 8, (NSUInteger)bytesPerRow, NULL, kCGImageAlphaOnly);
CGContextRef contextRef = CGBitmapContextCreate(bitmapData, (NSUInteger)width, (NSUInteger)height, 8, (NSUInteger)bytesPerRow, NULL, (kCGBitmapAlphaInfoMask & kCGImageAlphaOnly));

CGImageRef cgImage = self.CGImage;
CGRect rect = CGRectMake(0, 0, width, height);
Expand Down Expand Up @@ -172,4 +172,139 @@ - (UIImage *)imageByTrimmingTransparentPixelsRequiringFullOpacity:(BOOL)fullyOpa
return img;
}

/*
* Calculates the insets of white area around all sides of the image
*
* @param tolerance
* Maximal difference from white
*/
- (UIEdgeInsets)transparencyInsetsByCuttingWhitespace:(UInt8)tolerance
{
// Draw our image on that context
NSInteger width = (NSInteger)CGImageGetWidth([self CGImage]);
NSInteger height = (NSInteger)CGImageGetHeight([self CGImage]);
NSInteger bytesPerRow = width * (NSInteger)sizeof(uint8_t);

// Allocate array to hold alpha channel
uint8_t * bitmapData = calloc((size_t)(width * height), sizeof(uint8_t));

// Create grayscale image
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef contextRef = CGBitmapContextCreate(bitmapData, (NSUInteger)width, (NSUInteger)height, 8, (NSUInteger)bytesPerRow, colorSpace, (kCGBitmapAlphaInfoMask & kCGImageAlphaNone));

CGImageRef cgImage = self.CGImage;
CGRect rect = CGRectMake(0, 0, width, height);
CGContextDrawImage(contextRef, rect, cgImage);

// Sum all non-transparent pixels in every row and every column
uint16_t * rowSum = calloc((size_t)height, sizeof(uint16_t));
uint16_t * colSum = calloc((size_t)width, sizeof(uint16_t));

// Enumerate through all pixels
for (NSInteger row = 0; row < height; row++) {

for (NSInteger col = 0; col < width; col++) {

// Found darker pixel
if (bitmapData[row*bytesPerRow + col] <= UINT8_MAX - tolerance) {

rowSum[row]++;
colSum[col]++;

}
}
}

// Initialize crop insets and enumerate cols/rows arrays until we find non-empty columns or row
UIEdgeInsets crop = UIEdgeInsetsZero;

// Top
for (NSInteger i = 0; i < height; i++) {

if (rowSum[i] > 0) {

crop.top = i;
break;

}

}

// Bottom
for (NSInteger i = height - 1; i >= 0; i--) {

if (rowSum[i] > 0) {
crop.bottom = MAX(0, height - i - 1);
break;
}

}

// Left
for (NSInteger i = 0; i < width; i++) {

if (colSum[i] > 0) {
crop.left = i;
break;
}

}

// Right
for (NSInteger i = width - 1; i >= 0; i--) {

if (colSum[i] > 0) {

crop.right = MAX(0, width - i - 1);
break;

}
}

free(bitmapData);
free(colSum);
free(rowSum);

CGContextRelease(contextRef);

return crop;
}

- (UIImage *)imageByTrimmingWhitePixelsWithOpacity:(UInt8)tolerance
{
if (self.size.height < 2 || self.size.width < 2) {

return self;

}

CGRect rect = CGRectMake(0, 0, self.size.width * self.scale, self.size.height * self.scale);
UIEdgeInsets crop = [self transparencyInsetsByCuttingWhitespace:tolerance];

UIImage *img = self;

if (crop.top == 0 && crop.bottom == 0 && crop.left == 0 && crop.right == 0) {

// No cropping needed

} else {

// Calculate new crop bounds
rect.origin.x += crop.left;
rect.origin.y += crop.top;
rect.size.width -= crop.left + crop.right;
rect.size.height -= crop.top + crop.bottom;

// Crop it
CGImageRef newImage = CGImageCreateWithImageInRect([self CGImage], rect);

// Convert back to UIImage
img = [UIImage imageWithCGImage:newImage scale:self.scale orientation:self.imageOrientation];

CGImageRelease(newImage);
}

return img;
}

@end
12 changes: 12 additions & 0 deletions UIImage-Trim.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Pod::Spec.new do |s|
s.name = 'UIImage-Trim'
s.authors = { "Sachin Patel" => "me@gizmosachin.com" }
s.license = 'MIT'
s.summary = 'Category for trimming transparent pixels of an UIImage object.'
s.version = '1.0'
s.homepage = 'https://github.com/gizmosachin/UIImage-Trim'
s.source = { :git => "https://github.com/gizmosachin/UIImage-Trim.git", :tag => '1.0' }
s.frameworks = 'Foundation', 'UIKit'
s.platform = :ios, '7.0'
s.source_files = 'Source'
end

0 comments on commit a387b2e

Please sign in to comment.