神刀安全网

CIFilter_看了这个,你就可以打造自己的美图秀秀

上篇文章iOS_最全的二维码篇说要给大家简绍一下强大而好玩工具CIFilter,所以这今天晚上给大家分享一个demo。我保证你看了这篇文章之后,肯定能做出自己的美图工具,我发誓(虽然并没卵用)。

CIFilter,其实就是一个滤镜。喜欢摄影的小伙伴,可能接触过PS,而接触过PS的小伙伴,对滤镜肯定不陌生。而且有了解相关知识的小伙伴,对于颜色和图片处理的认知也一定信手捏来。什么RGB,什么CMYK,什么灰度图片,什么高斯模糊,什么锐化,什么对比度,什么饱和度,什么颜色通道,为什么值在255之间等等。我为什么知道这些,其实小Jorn我大一的时候,刚上大学,课不是很多,时间充足,那时候,都还不知道LOL(呵呵,现在,此处省略1W字),还带着高中的稚气和志气。想想要学点啥一技之长。记得高中时候,有次去拍一寸照,看那sb老板,不懂PS,硬是给我照片乱修。结果照片老丑,还硬坑我20块钱。所以大学就想到自己学学PS,在处理照片的时候可以自己修。而且,PS还可以做很多平面设计。说不定以后可以去做设计的工作。一个好的设计师,薪资还是很高的(^_^)。所以自己学了一年多的PS(堪称大神了,然并卵),后来学的差不多了。海报设计,网页设计,UI设计,还有其他各种设计,图文排版,图片处理,婚纱处理,P图等什么滴都自己做过(厉害吧)。大二的时候又学了一年的AI,后来还想学AE来着(因为大学嘛,越到后来,你懂得。游戏也开始玩起来了)。学了PS和AI,其实我还是觉得很不错的,不只在一个地方看到,PS和AI就像左右手,这也是做平面设计的工作者必备的两技能。一个负责位图,一个负责矢量图,功能都超强大。现在iOS上用的icon基本都是用这两工具设计的。虽然现在不慎混到了程序猿的大流。不过想想懂这也不是无可用武之地,至少在图片处理,颜色的认知上还有挺有帮助的(呵呵,安慰一下自己)。(扯远了。。。)

言归正传,你学会使用CIFilter,你就可以随意处理你想要的效果。系统给我们提供的滤镜种类是非常的多,不是十几个,是几十个。没错!

CoreImage是个非常强大框架,集图片的几乎所有操作编辑于一身,CIFilter只是其中的一个工具,主要作用是给图片渲染不同的效果
CIFilter的种类很多,所以苹果的官方文档也只能给出部分常用的种类的说明。
官方文档给出的部分说明:点击这里
虽然官方文档很简洁,但国外的大神们已经证明这是个相当强悍的框架,
不仅功能强大,而且可以直接使用GPU,效率奇高,甚至可以实时的对视频进行渲染。

下面让我们来看看,如何具体使用它:
首先你需要导入CoreImage.framework框架;进行Mac(不是iOS)开发的同学请导入QuartzCore.framework框架,包含在其中了。
然后我们先来看看3个主要的类:
CIContext:它与CoreGraphicsOpenGL context类似,所有CoreImage的处理流程都通过它来进行;
CIImage:它用来存放图片数据,可以通过UIImage,图片文件或像素数据创建;
CIFilter:通过它来定义过滤器的详细属性。
CIContext有两种初始化方法,分别对应GPUCPU

创建基于GPU的CIContext对象
context = [CIContext contextWithOptions: nil];
创建基于CPU的CIContext对象
context = [CIContext contextWithOptions: [NSDictionarydictionaryWithObject:[NSNumber numberWithBool:YES]
forKey:kCIContextUseSoftwareRenderer]];
一般采用第一种基于GPU的,因为效率要比CPU高很多,但是要注意的是基于GPU的CIContext对象无法跨应用访问。
比如你打开UIImagePickerController要选张照片进行美化,如果你直接在UIImagePickerControllerDelegate的委托方法里调用CIContext对象进行处理,那么系统会自动将其降为基于CPU的,速度会变慢,所以正确的方法应该是在委托方法里先把照片保存下来,回到主类里再来处理。

CIFilter的强大之处在于,可以叠加来得到多种效果。看过iOS_最全的二维码篇这篇文章的小伙伴肯定知道了什么叫叠加,其实如果你按那篇文章我说的练习一下,你就会发现,得到的图片也还是不过清晰。因为,二维码生成的原图太小,放大就很模糊。其实我在用PS处理手机拍的图片时,一开始少不了这三步,补点光,太暗;增加的对比度,不够鲜明;锐化一下,细节不过清晰。对,就是锐化一下。等下会让你获得一副清晰的二维码图。

首先让你知道,怎么查看到底有哪些滤镜:

        /* Categories */ //        public let kCICategoryDistortionEffect: String ///失真效果 //        public let kCICategoryGeometryAdjustment: String ///几何调整 //        public let kCICategoryCompositeOperation: String ///复合操作 //        public let kCICategoryHalftoneEffect: String ///半色调效果 //        public let kCICategoryColorAdjustment: String ///颜色调整 //        public let kCICategoryColorEffect: String ///颜色效果 //        public let kCICategoryTransition: String ///翻转 //        public let kCICategoryTileEffect: String ///瓦片效果 //        public let kCICategoryGenerator: String ///生成器 //        @available(iOS 5.0, *) //        public let kCICategoryReduction: String ///削减 //        public let kCICategoryGradient: String ///梯度 //        public let kCICategoryStylize: String ///风格 //        public let kCICategorySharpen: String ///锐化 //        public let kCICategoryBlur: String ///模糊 //        public let kCICategoryVideo: String ///视频 //        public let kCICategoryStillImage: String ///静态图片 //        public let kCICategoryInterlaced: String ///交叉 //        public let kCICategoryNonSquarePixels: String ///非方形像素 //        public let kCICategoryHighDynamicRange: String ///高动态范围 //        public let kCICategoryBuiltIn: String ///内建 //        @available(iOS 9.0, *) //        public let kCICategoryFilterGenerator: String ///滤镜生成器

这是系统含有的所有大类。
想知道有哪些filter类型或想查找想要的filter类型,可以通过先查找大的分类(如上),然后在查找子项。

        let names = CIFilter.filterNames(inCategory: kCICategoryGenerator) ///kCICategoryGenerator大类         print(names)

这样就会输出该大类包含的所有滤镜。如上会输出所有的生成器类型CIFilter种类:

 ///生成器大类所包含的所有生成器子类,如:"CICode128BarcodeGenerator"(条形码生成器),"CIQRCodeGenerator"(二维码生成器) //        ["CIAztecCodeGenerator", //         "CICheckerboardGenerator", //         "CICode128BarcodeGenerator", ///条形码生成器 //         "CIConstantColorGenerator", //         "CILenticularHaloGenerator", //         "CIPDF417BarcodeGenerator", //         "CIQRCodeGenerator", ///二维码生成器 //         "CIRandomGenerator", //         "CIStarShineGenerator", //         "CIStripesGenerator", //         "CISunbeamsGenerator"]

然后就可以创建滤镜对象了,有两方法,含参数的仅iOS8之后可用,iOS上不设输入参数,系统会使用默认值,但是mac是会报错,输入参数不明确:

/** Creates a new filter of type 'name'.          On OSX, all input values will be undefined.          On iOS, all input values will be set to default values. */         /// 要是是mac开发,创建filter对象必须提供输入参数,iOS可以忽略,系统会使用默认值。         //init?(name: String)         //@available(iOS 8.0, *) ///iOS 8.0 之后         //init?(name: String, withInputParameters params: [String : Any]?)

看看该滤镜需要设置那些输入参数,如此:

        let filter = CIFilter(name: "CIQRCodeGenerator")         let inpoutkeys = filter?.inputKeys ///查看这个filter的所有输入参数         let outputKeys = filter?.outputKeys ///查看这个filter的所有输出参数          print("inpoutkeys:",inpoutkeys)         print("outputKeys:",outputKeys)

设置参数用KVC来设置,常用的key,系统已经作为常量给出,可以cmd加鼠标左键点击CIFilter类名进去查看。
如上,二维码生成器滤镜需要量输入参数:

///eg.1 ///示例代码KVO         /// 1. 实例化二维码滤镜         let filter = CIFilter(name: "CIQRCodeGenerator")///二维码          /// 2. 恢复滤镜的默认属性 ///值得注意         filter?.setDefaults()          /// 3. 将字符串转换成二进制数据,(生成二维码所需的数据)         let string = "hello word"         let data = string.data(using: String.Encoding.utf8)///Swift 3.0          /// 4. 通过KVO把二进制数据添加到滤镜inputMessage中         filter?.setValue(data, forKey: "inputMessage")         filter?.setValue("H", forKey: "inputCorrectionLevel")          /// 5. 获得滤镜输出的图像         let outputImage = filter?.outputImage ///CIImage          /// 6. 将CIImage转换成UIImage,并放大显示         //let originQRCodeImage = UIImage(ciImage: outputImage!, scale: 0.07, orientation: UIImageOrientation.up) ///原生二维码图片 ///这样将图片放大会变得模糊

这样得到的originQRCodeImage是模糊的,把scale设为一时得到实际大小,但太小。在上篇文章我提过,需要进行重绘(效果80分)。这里我们可以使用缩放滤镜来缩放。生产高质量的、按比例缩放的源图像的版本(这是文档说明,然我并没发现有啥牛掰,还是模糊)。
CIFilter"CILanczosScaleTransform"(兰索斯缩放变化滤镜),但为了达到彩色的效果我们先把颜色滤镜加上,CIFliter"CIFalseColor"(伪色滤镜):

let colorFilter = CIFilter(name: "CIFalseColor")///颜色滤镜         colorFilter!.setDefaults()         colorFilter!.setValue(outputImage             , forKey:kCIInputImageKey)          colorFilter!.setValue(CIColor(red: 33.0 / 225.0, green: 192.0 / 225.0, blue: 174.0 / 225.0, alpha: 1.0), forKey:"inputColor0")///二维码元素(像素)         colorFilter!.setValue(CIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1), forKey:"inputColor1")///背景          let colorImgae = colorFilter!.outputImage
 let scaleFilter = CIFilter(name: "CILanczosScaleTransform") ///兰索斯缩放变化滤镜         scaleFilter?.setDefaults()         scaleFilter?.setValue(colorImgae, forKey: kCIInputImageKey)         scaleFilter?.setValue(1.0, forKey: kCIInputScaleKey)         scaleFilter?.setValue(1.0, forKey: kCIInputAspectRatioKey)         let scaleImage = scaleFilter?.outputImage

所以通过添加锐化滤镜来锐化一下,CIFilter"CISharpenLuminance"(亮度锐化,对光度有作用,度色度没影响):

 let sharpenFilter = CIFilter(name: "CISharpenLuminance") ///细节锐化滤镜         ///It operates on the luminance of the image; the chrominance of the pixels remains unaffected.         sharpenFilter?.setDefaults()         sharpenFilter?.setValue(scaleImage, forKey: kCIInputImageKey)         sharpenFilter?.setValue(10.0, forKey: kCIInputSharpnessKey)         let sharpenImage = sharpenFilter?.outputImage

最后得到图片:

let newQRCodeImage = UIImage(ciImage: sharpenImage!)         let imgBtn = UIButton(type: .custom)         imgBtn.frame = self.view.frame         imgBtn.setImage(newQRCodeImage, for: .normal)         self.view.addSubview(imgBtn)

通过参数的设置,得到的图片效果70分;

而在进行重绘后,再进行锐化处理的话,你就会发现效果是真的不错(95分)。

因为升为了Switft3.0代码,所以代码需要少量修改。主要就是Swift3.0把CoreGraphics的全局方法改为了实例方法,

func createUIimageWithCGImage(ciImage image: CIImage, widthAndHeightValue wh: CGFloat) -> CIImage {         let ciRect = image.extent.integral///根据容器得到适合的尺寸         let scale = min(wh / ciRect.width, wh / ciRect.height)          ///获取bitmap         let width  = size_t(ciRect.width * scale)          let height  = size_t(ciRect.height * scale)         let cs = CGColorSpaceCreateDeviceGray()///灰度颜色通道 ///CGColorSpaceRef          let info_UInt32 = CGImageAlphaInfo.none.rawValue         let bitmapRef = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: 0, space: cs, bitmapInfo: info_UInt32)          let contex = CIContext(options: nil) ///  创建基于GPU的CIContext对象,性能和效果更好         let bitmapImageRef = contex.createCGImage(image, from: CGRect(x: ciRect.origin.x, y: ciRect.origin.y, width: ciRect.size.width, height: ciRect.size.height)) ///CGImageRef          ///swift 3.0, 把全局方法改为了实例方法         bitmapRef!.interpolationQuality = CGInterpolationQuality.high///写入质量高,时间长         bitmapRef!.scaleBy(x: scale, y: scale) ///调整“画布”的缩放         bitmapRef?.draw(bitmapImageRef!, in: ciRect, byTiling: true)///绘制图片          ///保存         let scaledImage = bitmapRef!.makeImage() ///cgimage          ///bitmapRef和bitmapImageRef不用主动释放,Core Foundation自动管理         //let originImage = UIImage(CGImage: scaledImage!) ///原生灰度图片(灰色)          let ciImage = CIImage(cgImage: scaledImage!) ///ciimage         //let newQRCodeImage = UIImage(cgImage: scaledImage!) ///uiimage          return ciImage     }

附录:

    ///附:你要是细心,或者有点好奇心,你可能会问,为什么我们看到的二维码中间都有一个小图片,
///确实现在的大多二维码生成工具都喜欢中间贴上一个小图,但是上述生成的二维码并没有,
///其实这很简单,这也是我没有在这个小问题给出示例的原因。其实二维码在缺少小部分的情况下,并不影响存储信息的完整性
///所以小图片是另外加上去的,只是遮掉了一小块二维码内容,这并不影响什么。
///然而在一张图上添加另一张图,相信你也觉得这并不是什么问题。自己试试吧。
///如:用quartz2D drawimga的方法即可。

下图:1.锐化;2.重绘;3.重绘+锐化

CIFilter_看了这个,你就可以打造自己的美图秀秀
1.锐化;2.重绘;3.重绘+锐化.png

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » CIFilter_看了这个,你就可以打造自己的美图秀秀

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址