Last active
November 8, 2022 08:10
-
-
Save krooked/9c4c81557fc85bc61e51c0b4f3301e6e to your computer and use it in GitHub Desktop.
Swift: UIImage Crop Alpha
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I needed to do this in Swift 4, so here's what I've hacked together:
https://gist.github.com/AdamLantz/d5d841e60583e740c0b5f515ba5064fb