【问题标题】:SWIFT 3 - CGImage copy always nilSWIFT 3 - CGImage 副本始终为零
【发布时间】:2017-10-06 18:23:18
【问题描述】:

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

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] 所以也没问题。

非常感谢您的宝贵时间。

【问题讨论】:

  • "colorMasking 就像 colorMasking = [222,255,222,255,222,255]" 这就是问题所在。这些值是错误的。

标签: ios swift swift3 cgimage


【解决方案1】:

我会多研究一下这个问题,以找出真正的问题。

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

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

设置一些断点,逐步完成,让我知道你发现了什么。

______________________________编辑一个______________________________

所以快速查看 docs for copy(maskingColorComponents:) 似乎组件数组可能存在问题。

组件:

一组颜色组件,指定颜色或颜色范围以遮盖图像。该数组必须包含 2N 个值 { min1, max1, ... min[N], max[N] } 其中 N 是图像颜色空间中的分量数。组件中的每个值都必须是有效的图像样本值。如果图像具有整数像素分量,则每个值必须在 [0 .. 2**bitsPerComponent - 1] 范围内(其中 bitsPerComponent 是图像的位数/分量)。如果图像具有浮点像素分量,则每个值可以是任何浮点数,它是有效的颜色分量。

您确定您的价值观对您的形象有效吗?

【讨论】:

    【解决方案2】:

    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)
    
        }
    
    }
    

    【讨论】:

    • 这就是问题所在。问题不在于颜色遮罩,谢谢。
    • 如果你熟悉CGImage,你能告诉我这个函数的结果吗,因为在屏幕上结果似乎是一个透明的图像(我们剪切了传递的颜色,所以我们看到了 UIViewController 背景。但是,当我尝试将此结果保存为带有 UIImagePNGRepresentation 的 à PNG 时,它似乎有黑色背景。Ty
    • 哦 @DonMag 非常感谢你,你是真正的 CGImage 英雄。谢谢大家。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-21
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 2016-05-02
    相关资源
    最近更新 更多