Swift Image Crop Out Transparent Pixels (Swift 2.0)
extension UIImage { | |
func imageByCroppingTransparentPixels() -> UIImage { | |
let rect = self.cropRectForImage() | |
return cropImage(toRect: rect) | |
} | |
func cropRectForImage(image:UIImage) -> CGRect { | |
let imageAsCGImage = image.CGImage | |
let context:CGContextRef? = self.createARGBBitmapContext(imageAsCGImage!) | |
if let context = context { | |
let width = Int(CGImageGetWidth(imageAsCGImage)) | |
let height = Int(CGImageGetHeight(imageAsCGImage)) | |
let rect:CGRect = CGRect(x: 0.0, y: 0.0, width: CGFloat(width), height: CGFloat(height)) | |
CGContextDrawImage(context, rect, imageAsCGImage) | |
var lowX:Int = width | |
var lowY:Int = height | |
var highX:Int = 0 | |
var highY:Int = 0 | |
let data:UnsafeMutablePointer<Void>? = CGBitmapContextGetData(context) | |
if let data = data { | |
let dataType:UnsafeMutablePointer<UInt8>? = UnsafeMutablePointer<UInt8>(data) | |
if let dataType = dataType { | |
for y in 0..<height { | |
for x in 0..<width { | |
let pixelIndex:Int = (width * y + x) * 4 /* 4 for A, R, G, B */; | |
if (dataType[pixelIndex] != 0) { //Alpha value is not zero; pixel is not transparent. | |
if (x < lowX) { lowX = x }; | |
if (x > highX) { highX = x }; | |
if (y < lowY) { lowY = y}; | |
if (y > highY) { highY = y}; | |
} | |
} | |
} | |
} | |
free(data) | |
} else { | |
return CGRectZero | |
} | |
return CGRect(x: CGFloat(lowX), y: CGFloat(lowY), width: CGFloat(highX-lowX), height: CGFloat(highY-lowY)) | |
} | |
return CGRectZero | |
} | |
func createARGBBitmapContext(inImage: CGImageRef) -> CGContext { | |
var bitmapByteCount = 0 | |
var bitmapBytesPerRow = 0 | |
//Get image width, height | |
let pixelsWide = CGImageGetWidth(inImage) | |
let pixelsHigh = CGImageGetHeight(inImage) | |
// Declare the number of bytes per row. Each pixel in the bitmap in this | |
// example is represented by 4 bytes; 8 bits each of red, green, blue, and | |
// alpha. | |
bitmapBytesPerRow = Int(pixelsWide) * 4 | |
bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh) | |
// Use the generic RGB color space. | |
let colorSpace = CGColorSpaceCreateDeviceRGB() | |
// Allocate memory for image data. This is the destination in memory | |
// where any drawing to the bitmap context will be rendered. | |
let bitmapData = malloc(bitmapByteCount) | |
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue) | |
// Create the bitmap context. We want pre-multiplied ARGB, 8-bits | |
// per component. Regardless of what the source image format is | |
// (CMYK, Grayscale, and so on) it will be converted over to the format | |
// specified here by CGBitmapContextCreate. | |
let context = CGBitmapContextCreate(bitmapData, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, bitmapInfo.rawValue) | |
return context! | |
} | |
} |
This comment has been minimized.
This comment has been minimized.
ULazdins
commented
Mar 5, 2019
I guess, you can modify line 27 to get R, G, B. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
fraserscottmorrison commentedNov 7, 2016
How could I modify this to crop white pixels? Thanks!