SWIFT 3 - CGImage 副本始终为零

SWIFT 3 - CGImage copy always nil

遇到这个问题并尝试修复它几个小时。

func changeColorByTransparent(colorMasking : [CGFloat]) {

    UIGraphicsBeginImageContext(self.symbolImageView.frame.size)
    self.symbolImageView.layer.render(in: UIGraphicsGetCurrentContext()!)
    self.symbolImageView.image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    if let image = self.symbolImageView.image {
        print("image ok")
        if let cgimage = image.cgImage {
            print("cgimage ok")
            if let imageRef = cgimage.copy(maskingColorComponents: colorMasking) {
                print("imageRef ok")
                self.symbolImageView.image = UIImage(cgImage: imageRef, scale: (self.symbolImageView.image?.scale)!, orientation: (self.symbolImageView.image?.imageOrientation)!)
            }
        }
    }
}

控制台给我:

image ok
cgimage ok

它总是告诉我 imageRef 为 nil 但调试找到了 symbolImageView.image 的图像并且该图像是 JPG 格式。 colorMasking 就像 colorMasking = [222,255,222,255,222,255] 所以没问题。

非常感谢您的宝贵时间。

我会再仔细研究一下,找出问题所在。

让我们从这个开始:将您的 if-let 分解为嵌套的 if-let。只是为了弄清楚哪个值返回 nil。

if let image = self.symbolImageView.image? {
   if let cgImage = image.cgImage {
      ...
   }
}

设置一些断点,单步执行,让我知道你发现了什么。

______________________________EDIT ONE______________________________

所以快速查看一下 docs 的 copy(maskingColorComponents:) 组件数组似乎有问题。

组件:

An array of color components that specify a color or range of colors to mask the image with. The array must contain 2N values { min1, max1, ... min[N], max[N] } where N is the number of components in color space of image. Each value in components must be a valid image sample value. If image has integer pixel components, then each value must be in the range [0 .. 2**bitsPerComponent - 1] (where bitsPerComponent is the number of bits/component of image). If image has floating-point pixel components, then each value may be any floating-point number which is a valid color component.

您确定您的值对您的图像有效吗?

copy(maskingColorComponents components: [CGFloat])的来源不能有 alpha 组件。使用 UIGraphicsGetImageFromCurrentImageContext 获取图像的方式会产生 alpha 分量。

试试这个:

func changeColorByTransparent(imgView: UIImageView, cMask: [CGFloat]) -> UIImage? {

    var returnImage: UIImage?

    if let capImage = imgView.image {

        let sz = capImage.size

        UIGraphicsBeginImageContextWithOptions(sz, true, 0.0)
        capImage.draw(in: CGRect(origin: CGPoint.zero, size: sz))
        let noAlphaImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        let noAlphaCGRef = noAlphaImage?.cgImage

        if let imgRefCopy = noAlphaCGRef?.copy(maskingColorComponents: cMask) {

            returnImage = UIImage(cgImage: imgRefCopy)

        }

    }

    return returnImage

}

并这样称呼它:

var cMask : [CGFloat] = []

cMask = [222, 255, 222, 255, 222, 255]

let newImage = changeColorByTransparent(imgView: symbolImageView, cMask: cMask)

(假设您有一个名为 "symbolImageView" 的 UIImageVIew

并且,在保存生成的图像时解决奇怪的 alpha 通道问题:

func saveImageWithAlpha(theImage: UIImage, destFile: URL) -> Void {

    // odd but works... solution to image not saving with proper alpha channel
    UIGraphicsBeginImageContext(theImage.size)
    theImage.draw(at: CGPoint.zero)
    let saveImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    if let img = saveImage, let data = UIImagePNGRepresentation(img) {

        try? data.write(to: destFile)

    }

}