Skip to content

Instantly share code, notes, and snippets.

@krooked
Last active November 8, 2022 08:10
Show Gist options
  • Save krooked/9c4c81557fc85bc61e51c0b4f3301e6e to your computer and use it in GitHub Desktop.
Save krooked/9c4c81557fc85bc61e51c0b4f3301e6e to your computer and use it in GitHub Desktop.
Swift: UIImage Crop Alpha
import Foundation
import UIKit
/* Extension for croping transparent pixels
example:
let image: UIImage = UIImage(imageLiteral: "YOUR_IMAGE")
let uiImageView = UIImageView(image: image.cropImageByAlpha())
view.addSubview(uiImageView)
Code was basically done here:
http://stackoverflow.com/questions/9061800/how-do-i-autocrop-a-uiimage/13922413#13922413
http://www.markj.net/iphone-uiimage-pixel-color/
*/
extension UIImage {
func cropImageByAlpha() -> UIImage {
let cgImage = self.CGImage
let context = createARGBBitmapContextFromImage(cgImage!)
let height = CGImageGetHeight(cgImage)
let width = CGImageGetWidth(cgImage)
var rect: CGRect = CGRectMake(0, 0, CGFloat(width), CGFloat(height))
CGContextDrawImage(context, rect, cgImage)
let data = UnsafePointer<CUnsignedChar>(CGBitmapContextGetData(context))
var minX = width
var minY = height
var maxX: Int = 0
var maxY: Int = 0
//Filter through data and look for non-transparent pixels.
for y in 0..<height {
for x in 0..<width {
let pixelIndex = (width * y + x) * 4 /* 4 for A, R, G, B */
if data[Int(pixelIndex)] != 0 { //Alpha value is not zero pixel is not transparent.
if (x < minX) {
minX = x
}
if (x > maxX) {
maxX = x
}
if (y < minY) {
minY = y
}
if (y > maxY) {
maxY = y
}
}
}
}
rect = CGRectMake(CGFloat(minX), CGFloat(minY), CGFloat(maxX-minX), CGFloat(maxY-minY))
let imageScale:CGFloat = self.scale
let cgiImage = CGImageCreateWithImageInRect(self.CGImage, rect)
return UIImage(CGImage: cgiImage!, scale: imageScale, orientation: self.imageOrientation)
}
private func createARGBBitmapContextFromImage(inImage: CGImageRef) -> CGContextRef? {
let width = CGImageGetWidth(inImage)
let height = CGImageGetHeight(inImage)
let bitmapBytesPerRow = width * 4
let bitmapByteCount = bitmapBytesPerRow * height
let colorSpace = CGColorSpaceCreateDeviceRGB()
if colorSpace == nil {
return nil
}
let bitmapData = malloc(bitmapByteCount)
if bitmapData == nil {
return nil
}
let context = CGBitmapContextCreate (bitmapData, width, height, 8, bitmapBytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedFirst.rawValue)
return context
}
}
@AdamLantz
Copy link

I needed to do this in Swift 4, so here's what I've hacked together:
https://gist.github.com/AdamLantz/d5d841e60583e740c0b5f515ba5064fb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment