UIImage剪裁去除透明像素

7

我需要帮忙使用 Swift 4 剪裁 UIImage 中透明像素后创建完美清晰的图像。

我想创建一个去除透明颜色的图像。为此,我使用了以下代码。但是它会模糊图像,并出现小小的方形矩形。

以下是代码:

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


我不太明白这个问题,你能否提供一个具有透明像素的UIImage示例?你从哪里获取这个图像?是通过编程创建的吗?是的,我看到了边缘上有一些模糊,我理解这个问题,但我无法弄清楚如何重现这个问题,以便准确地了解发生了什么。 - Mihai Erős
@MihaiErős,我已经加入了透明图像,供您参考。 - Mehul
我看到在“裁剪”之前的图像边缘有那些方块。 - Mihai Erős
1个回答

1

在这行代码中,仅检查 alpha 分量是否大于零可能不足够:

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

也许你可以将阈值设置得更高一些:if(a > 0.5),或者更高。 if (a == 1) 将是极限,它将确保完全没有透明度。
如果您希望 imageCroppedBgimgWithClearBackgroung 具有相同的大小,则将包含 imgWithClearBackgroungUIImageView 的内容模式设置为 .scaleAspectFit
let imageCroppedBg = imgWithClearBackgroung.cropAlpha()
imageView.image = imageCroppedBg
imageView.contentMode = .scaleAspectFit

想要了解更多有关内容模式的信息,请查看这里

附言:在Swift中,行末不需要加;


注意,从行末删除了';'。我也尝试过0.5,但效果不佳,只有微小的改变。谢谢您的回答,您还有其他想法或详细回答吗?提前致谢。 - Mehul
1
@Mehul 如果你在Photoshop中检查所提供的png文件,你会发现额外像素的不透明度为0.77。因此,阈值应该进行调整。在极端情况下,你可能需要一个alpha a == 1 - ielyamani
好的,谢谢。我会检查并尽快告诉你。 :-) - Mehul
是的,它可以工作,但图像会被拉伸。图像尝试适应原始宽度和高度,因此输出图像看起来像是被拉伸了。您能否帮助我获取输出图像的高度和宽度,这样在删除 alpha 像素后我们就可以得到完美的图像。 提前致谢。 - Mehul
@Mehul,你能否编辑你的问题并附上你目前的结果? - ielyamani
是的,我会更新,但我的iPhone已经进水了。我很快就会更新的,兄弟。 - Mehul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接