How do I autocrop a UIImage?

后端 未结 6 495
南方客
南方客 2020-12-23 15:04

I have a UIImage which contains a shape; the rest is transparent. I\'d like to get another UIImage by cropping out as much of the transparent part as possible, still retain

6条回答
  •  死守一世寂寞
    2020-12-23 15:59

    Swift 4

    extension UIImage {
        
        func cropAlpha() -> UIImage {
            
            let cgImage = self.cgImage!;
            
            let width = cgImage.width
            let height = cgImage.height
            
            let colorSpace = CGColorSpaceCreateDeviceRGB()
            let bytesPerPixel:Int = 4
            let bytesPerRow = bytesPerPixel * width
            let bitsPerComponent = 8
            let bitmapInfo: UInt32 = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue
            
            guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo),
                let ptr = context.data?.assumingMemoryBound(to: UInt8.self) else {
                    return self
            }
            
            context.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: width, height: height))
            
            var minX = width
            var minY = height
            var maxX: Int = 0
            var maxY: Int = 0
            
            for x in 1 ..< width {
                for y in 1 ..< height {
                    
                    let i = bytesPerRow * Int(y) + bytesPerPixel * Int(x)
                    let a = CGFloat(ptr[i + 3]) / 255.0
                    
                    if(a>0) {
                        if (x < minX) { minX = x };
                        if (x > maxX) { maxX = x };
                        if (y < minY) { minY = y};
                        if (y > maxY) { maxY = y};
                    }
                }
            }
            
            let rect = CGRect(x: CGFloat(minX),y: CGFloat(minY), width: CGFloat(maxX-minX), height: CGFloat(maxY-minY))
            let imageScale:CGFloat = self.scale
            let croppedImage =  self.cgImage!.cropping(to: rect)!
            let ret = UIImage(cgImage: croppedImage, scale: imageScale, orientation: self.imageOrientation)
            
            return ret;
        }
        
    }
    

提交回复
热议问题