Skip to content

Instantly share code, notes, and snippets.

@gregpardo
Last active July 19, 2019 12:58
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gregpardo/b69c6cdbec8276df19b9 to your computer and use it in GitHub Desktop.
Save gregpardo/b69c6cdbec8276df19b9 to your computer and use it in GitHub Desktop.
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!
}
}
@fraserscottmorrison
Copy link

How could I modify this to crop white pixels? Thanks!

@ULazdins
Copy link

ULazdins commented Mar 5, 2019

How could I modify this to crop white pixels? Thanks!

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