Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIImage Crop Out Transparent Pixels

I need help to create perfect clear image after cropping transparent pixel from UIImage using swift 4.

I want to create image with remove transparent color, So for that i have used below code. But it blur image with small small square rectangles appears.

Using of below code

let imageCroppedBg = imgWithClearBackgroung!.cropAlpha()


//UIImage extension
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;
    }
}

Output blurred & small square in small

Image with Alpha/transparent pixel

like image 282
Mehul Avatar asked Aug 20 '18 09:08

Mehul


1 Answers

Checking that the alpha component is just > zero maybe not enough in this line:

if(a>0) {
    if (x < minX) { minX = x }
    if (x > maxX) { maxX = x }
    if (y < minY) { minY = y }
    if (y > maxY) { maxY = y }
}

Maybe you could make the threshold higher : if(a > 0.5) or even higher. if (a == 1) would be the limit and it would guarantee that there is no transparency at all.

If you'd like to have the imageCroppedBg with the same size of imgWithClearBackgroung, then set the content mode of the UIImageView containing imgWithClearBackgroung to .scaleAspectFit:

let imageCroppedBg = imgWithClearBackgroung.cropAlpha()
imageView.image = imageCroppedBg
imageView.contentMode = .scaleAspectFit

For more on content modes, have a look here.

P.S: In Swift the ; is not necessary at the end of the line.

like image 154
ielyamani Avatar answered Nov 11 '22 07:11

ielyamani