将 UIImage 转换为灰度保持图像质量 [英] Convert UIImage to grayscale keeping image quality
问题描述
我有这个扩展(在 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.none.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 Graphics
或 OpenGL 上下文
.有关更多信息,请访问
答案 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屋!