将 UIImage 转换为灰度保持图像质量 [英] Convert UIImage to grayscale keeping image quality

查看:27
本文介绍了将 UIImage 转换为灰度保持图像质量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个扩展(在 obj-c 中找到,我将它转换为 Swift3)以获得相同的 UIImage 但灰度:

public func getGrayScale() ->用户界面图像{让 imgRect = CGRect(x: 0, y: 0, width: width, height: height)让 colorSpace = CGColorSpaceCreateDeviceGray()let context = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.no​​ne.rawValue).rawValue)context?.draw(self.cgImage!, in: imgRect)让 imageRef = context!.makeImage()让 newImg = UIImage(cgImage: imageRef!)返回新的Img}

我可以看到灰色图像,但它的质量很差...我能看到的唯一与质量相关的是上下文构造函数中的 bitsPerComponent: 8.但是查看 Apple 的文档,这就是我得到的:

显示iOS只支持8bpc...为什么我不能提高质量?

解决方案

试试下面的代码:

注意:代码已更新并已修复错误...

  • 在 Swift 3 中测试的代码.
  • originalImage 是您尝试转换的图像.

答案 1:

 var context = CIContext(options: nil)

更新: CIContext 是处理渲染的核心图像组件,核心图像的所有处理都在CIContext.这有点类似于 Core GraphicsOpenGL 上下文.有关更多信息,请访问

答案 2 的输出:

改进答案:

答案 2:在应用 coreImage 过滤器之前自动调整输入图像

var context = CIContext(options: nil)func Noir() {//自动调整输入图像var inputImage = CIImage(image: originalImage.image!)让选项:[String : AnyObject] = [CIDetectorImageOrientation:1 as AnyObject]让过滤器 = inputImage!.autoAdjustmentFilters(options: options)对于过滤器:过滤器中的 CIFilter {filter.setValue(inputImage, forKey: kCIInputImageKey)inputImage = filter.outputImage}让 cgImage = context.createCGImage(inputImage!, from: inputImage!.extent)self.originalImage.image = UIImage(cgImage: cgImage!)//应用黑色过滤器让 currentFilter = CIFilter(name: "CIPhotoEffectTonal")currentFilter!.setValue(CIImage(image: UIImage(cgImage: cgImage!)), forKey: kCIInputImageKey)让输出 = currentFilter!.outputImage让 cgimg = context.createCGImage(output!, from: output!.extent)让处理图像 = UIImage(cgImage: cgimg!)originalImage.image = 处理过的图像}

注意:如果你想看到更好的结果.你应该在真实设备上测试你的代码,而不是在模拟器中..

I have this extension (found in obj-c and I converted it to Swift3) to get the same UIImage but grayscaled:

public func getGrayScale() -> UIImage
{
    let imgRect = CGRect(x: 0, y: 0, width: width, height: height)

    let colorSpace = CGColorSpaceCreateDeviceGray()

    let context = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).rawValue)
    context?.draw(self.cgImage!, in: imgRect)

    let imageRef = context!.makeImage()
    let newImg = UIImage(cgImage: imageRef!)

    return newImg
}

I can see the gray image but its quality is pretty bad... The only thing I can see that's related to the quality is bitsPerComponent: 8 in the context contructor. However looking at Apple's doc, here is what I get:

It shows that iOS only supports 8bpc... Thus why can't I improve the quality ?

解决方案

Try below code:

Note: code Updated and error been fixed...

  • Code tested in Swift 3.
  • originalImage is the image that you trying to convert.

Answer 1:

     var context = CIContext(options: nil)

Update: CIContext is the Core Image component that handles rendering and All of the processing of a core image is done in a CIContext. This is somewhat similar to a Core Graphics or OpenGL context.For more info available in Apple Doc.

     func Noir() {

        let currentFilter = CIFilter(name: "CIPhotoEffectNoir") 
        currentFilter!.setValue(CIImage(image: originalImage.image!), forKey: kCIInputImageKey)
        let output = currentFilter!.outputImage 
        let cgimg = context.createCGImage(output!,from: output!.extent)
        let processedImage = UIImage(cgImage: cgimg!)
        originalImage.image = processedImage
      }

Also you need to Considered following filter that can produce similar effect

  • CIPhotoEffectMono
  • CIPhotoEffectTonal

Output from Answer 1:

Output from Answer 2:

Improved answer :

Answer 2: Auto adjusting input image before applying coreImage filter

var context = CIContext(options: nil)

func Noir() {


    //Auto Adjustment to Input Image
    var inputImage = CIImage(image: originalImage.image!)
    let options:[String : AnyObject] = [CIDetectorImageOrientation:1 as AnyObject]
    let filters = inputImage!.autoAdjustmentFilters(options: options)

    for filter: CIFilter in filters {
       filter.setValue(inputImage, forKey: kCIInputImageKey)
   inputImage =  filter.outputImage
      }
    let cgImage = context.createCGImage(inputImage!, from: inputImage!.extent)
    self.originalImage.image =  UIImage(cgImage: cgImage!)

    //Apply noir Filter
    let currentFilter = CIFilter(name: "CIPhotoEffectTonal") 
    currentFilter!.setValue(CIImage(image: UIImage(cgImage: cgImage!)), forKey: kCIInputImageKey)

    let output = currentFilter!.outputImage 
    let cgimg = context.createCGImage(output!, from: output!.extent)
    let processedImage = UIImage(cgImage: cgimg!)
    originalImage.image = processedImage

}

Note: If you want to see the better result.You should be testing your code on real device not in the simulator...

这篇关于将 UIImage 转换为灰度保持图像质量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆