Swift 的图像处理具有随机效果

Image manipulation with Swift has random effects

我在 Swift 中有这个 ImageProcessor(这不是我的),我试图将它与我制作的一些过滤器一起使用,但在尝试时我注意到有一些随机噪音.

为了测试这一点,我制作了一个自定义过滤器 NoFilter,它什么都不做。

public class NoFilter : ImageFilterProtocol{
    public func apply(pixel: Pixel) -> Pixel {
        return pixel
    }   
}

这应该输出与它获得的相同的图像,有时它会在图像中产生随机错误。

例如:

请注意它是相同的代码,但每次都会产生不同的错误。题的最后是link自己试一下,每次跑起来都不一样。是什么原因造成的?

程序的当前流程是 ImageProcessor 接收图像并将其转换为 RGBAImage,然后当使用过滤器调用 apply 时,它将过滤器应用到RGBAImage 中的每个像素(在本例中是 无过滤器 )。最后,当 getImage 被调用时,它将 RGBAImage 转换回 UIImage。这表明从 and/or 到 RGBAImage 的转换可能有问题,但我找不到任何问题。

public struct RGBAImage {
    public var pixels: UnsafeMutableBufferPointer<Pixel>
    
    public var width: Int
    public var height: Int
    
    public init?(image: UIImage) {
        guard let cgImage = image.CGImage else { return nil }
        
        // Redraw image for correct pixel format
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        
        var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue
        bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue
        
        width = Int(image.size.width)
        height = Int(image.size.height)
        let bytesPerRow = width * 4
        
        let imageData = UnsafeMutablePointer<Pixel>.alloc(width * height)
        
        guard let imageContext = CGBitmapContextCreate(imageData, width, height, 8, bytesPerRow, colorSpace, bitmapInfo) else { return nil }
        CGContextDrawImage(imageContext, CGRect(origin: CGPointZero, size: image.size), cgImage)
        
        pixels = UnsafeMutableBufferPointer<Pixel>(start: imageData, count: width * height)
    }
    
    public func toUIImage() -> UIImage? {
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue
        bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue
        
        let bytesPerRow = width * 4
        
        let imageContext = CGBitmapContextCreateWithData(pixels.baseAddress, width, height, 8, bytesPerRow, colorSpace, bitmapInfo, nil, nil)
        
        guard let cgImage = CGBitmapContextCreateImage(imageContext) else {return nil}
        let image = UIImage(CGImage: cgImage)
        
        return image
    }
}

This is the code我正在测试,请试一下。

有什么想法吗?

编辑:将我的代码上传到 git,因此可以在线查看。

您在将图像绘制到其中时忘记清除图像上下文。尝试添加对 CGContextClearRect:

的调用
let rect = CGRect(origin: CGPointZero, size: image.size)
CGContextClearRect(imageContext, rect)    // Avoid undefined pixels!
CGContextDrawImage(imageContext, rect, cgImage)

这将避免未定义的像素从图像的透明区域下方窥视。