【问题标题】:UIImageJPEGRepresentation returns nilUIImageJPEGRepresentation 返回 nil
【发布时间】:2015-06-26 07:02:06
【问题描述】:

我正在使用 CIFilters 将图像转换为灰度并应用一些图像处理效果。在 UIImageView 中显示输出是可行的;图像显示并按预期进行了修改。

但是,调用 UIImageJPEGRepresentation 似乎每次都没有返回数据。它永远不会起作用。 使用原始彩色图像调用 UIImageJPEGRepresentation 可以正常工作。

这里发生了什么?为什么显示图像正常时 jpeg 转换会失败?没有抛出异常(设置异常断点,它没有被命中)并且控制台中没有出现任何消​​息。

let _cicontext = CIContext(options:nil)

// Set up grayscale and blur filters:
let grayIze = CIFilter(name: "CIColorControls")
let blur = CIFilter(name: "CIGaussianBlur")
grayIze.setValue(0, forKey:kCIInputSaturationKey)
grayIze.setValue(0.5, forKey: kCIInputBrightnessKey)
blur.setValue(4, forKey: kCIInputRadiusKey)

// Go!
let originalImage = CIImage(image: colorImageThatDefinitelyExists)
grayIze.setValue(originalImage, forKey: kCIInputImageKey)
blur.setValue(grayIze.outputImage, forKey: kCIInputImageKey)

let output = UIImage(CIImage: blur.outputImage)
let imageData: NSData? = UIImageJPEGRepresentation(output, 1.0) // Returns nil!?

编辑:这是基于Arbitur's answer的工作代码:

// Define an image context at the class level, which will only be initialized once:
static let imageContext = CIContext(options:nil)

// And here's the updated code in a function:
class func convertToGrayscale(image: UIImage)->UIImage?
{
    // Set up grayscale and blur filters:
    let filter1_grayIze = CIFilter(name: "CIColorControls")
    let filter2_blur = CIFilter(name: "CIGaussianBlur")
    filter1_grayIze.setValue(0, forKey:kCIInputSaturationKey)
    filter1_grayIze.setValue(0.5, forKey: kCIInputBrightnessKey)
    filter2_blur.setValue(4, forKey: kCIInputRadiusKey)

    // Go!
    let originalImage = CIImage(image: image)
    filter1_grayIze.setValue(originalImage, forKey: kCIInputImageKey)
    filter2_blur.setValue(filter1_grayIze.outputImage, forKey: kCIInputImageKey)
    let outputCIImage = filter2_blur.outputImage

    let temp:CGImageRef = imageContext.createCGImage(outputCIImage, fromRect: outputCIImage.extent())
    let ret = UIImage(CGImage: temp)
    return ret
}

// And finally, the function call:
    if let grayImage = ProfileImage.convertToGrayscale(colorImage)
    {
        let imageData: NSData? = UIImageJPEGRepresentation(grayImage, 1.0)
    }

【问题讨论】:

  • ret 中的 UIImageJPEGRepresentation(ret, 1.0) 是什么?我看不到它在您的代码中的定义位置。
  • 问题中的复制/粘贴错误。已编辑。
  • 尝试先将其制作为 CGImage,然后再制作 UIImage。我以前在 CIImage 上遇到过这个问题。
  • 成功了!知道为什么吗?如果您将评论作为答案发表,我会接受。谢谢!
  • 我认为这可能与您提供给 UIImage 的底层格式有关。例如,如果我将 AVCaptureStillImageOutput 的输出设置设置为imageOutput.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG],我可以使用直接从 CIImage 创建 UIImage 并成功使用 UIImageJPEGRepresentation。但是,如果我将输出设置设置为 imageOutput.outputSettings = [kCVPixelBufferPixelFormatTypeKey : NSNumber(unsignedInt: kCVPixelFormatType_32BGRA)],那么我必须转换为中间 CGImage。

标签: ios swift uiimage cifilter


【解决方案1】:

UIImageJPEGRepresentation 似乎使用了UIImageCGImage 属性。问题是,当您使用CIImage 初始化UIImage 时,该属性为nil

我的解决方案是在UIImageJPEGRepresentation 调用之前添加以下块:

上次更新 Swift 5.1

if image.cgImage == nil {
    guard 
        let ciImage = image.ciImage, 
        let cgImage = CIContext(options: nil).createCGImage(ciImage, from: ciImage.extent) 
    else { 
         return nil 
    }

    image = UIImage(cgImage: cgImage)
}

【讨论】:

  • 太棒了,这就像一个魅力。不确定我是否会偶然发现 nil CIImage 属性。
【解决方案2】:

我之前在使用 CIImage 时遇到过问题,为了解决这个问题,我用 CIImage 制作了一个 CGImage,然后用 CGImage 制作了一个 UIImage。

【讨论】:

  • 建议:您的答案可以通过发布完成此操作所需的代码来改进。
【解决方案3】:

丹尼尔的回答很好。在他的答案下方转换为在 Swift4 中使用。

Swift4

    if image?.cgImage == nil {
        guard let ciImage = image?.ciImage, let cgImage = CIContext(options: nil).createCGImage(ciImage, from: ciImage.extent) else { return }

        image = UIImage(cgImage: cgImage)
    }

【讨论】:

    猜你喜欢
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 2019-06-20
    • 2017-12-16
    • 2014-09-27
    • 2017-06-11
    相关资源
    最近更新 更多