项目中要实现高斯模糊的效果,今天看了下Core Image这块的内容, 主要包括CIImage、CIFilter、CIContext、CIDetector(检测)、CIFeature(特征)等类。

今天先记录下CIImage、CIFilter、CIContext三个类的使用。

一、基本的滤镜效果需要以下步骤

1.创建CIImage对象

2.创建CIContext对象用作画布

3.创建CIFilter对象

4.输出滤镜

二、创建上面三个对象的API

1.创建CIImage对象 主要通过以下方法( 方法有好多种  具体查看类CIImage)

+ (CIImage *)imageWithCGImage:(CGImageRef)image;
+ (CIImage *)imageWithCGLayer:(CGLayerRef)layer;
+ (nullable CIImage *)imageWithContentsOfURL:(NSURL *)url;
+ (nullable CIImage *)imageWithData:(NSData *)data;
- (instancetype)initWithCGImage:(CGImageRef)image;
- (nullable instancetype)initWithData:(NSData *)data;
- (nullable instancetype)initWithContentsOfURL:(NSURL *)url;
- (instancetype)initWithColor:(CIColor *)color;

2.创建CIContext对象

CIContext 构造函数contextWithOptions:的输入是一个NSDictionary。 它规定了各种选项,包括颜色格式以及内容是否应该运行在CPU或是GPU上。

 CIContext *context=[CIContext contextWithOptions:nil];

在该类中还有一些其他方法

- (void)drawImage:(CIImage *)image
          atPoint:(CGPoint)atPoint
         fromRect:(CGRect)fromRect NS_DEPRECATED(10_4,10_8, 5_0,6_0);

/* Render the rectangle 'fromRect' of 'image' to the rectangle 'inRect' in the
 * context's destination. */
- (void)drawImage:(CIImage *)image
           inRect:(CGRect)inRect
         fromRect:(CGRect)fromRect;

/* Render the region 'fromRect' of image 'image' into a temporary buffer using
 * the context, then create and return a new CoreGraphics image with
 * the results. The caller is responsible for releasing the returned
 * image. */
- (CGImageRef)createCGImage:(CIImage *)image
                   fromRect:(CGRect)fromRect
CF_RETURNS_RETAINED;

/* Create a new CGImage from the specified subrect of the image. If
 * non-nil the new image will be created in the specified format and
 * colorspace. */
- (CGImageRef)createCGImage:(CIImage *)image
                   fromRect:(CGRect)fromRect
                     format:(CIFormat)format
                 colorSpace:(nullable CGColorSpaceRef)colorSpace

3.创建CIFilter对象

1、创建滤镜对象

+ (nullable CIFilter *) filterWithName:(NSString *) name;

/** Creates a new filter of type 'name'.
 The filter's input parameters are set from the list of key-value pairs which must be nil-terminated.
 On OSX, any of the filter input parameters not specified in the list will be undefined.
 On iOS, any of the filter input parameters not specified in the list will be set to default values. */
+ (nullable CIFilter *)filterWithName:(NSString *)name
                        keysAndValues:key0, ... NS_REQUIRES_NIL_TERMINATION NS_SWIFT_UNAVAILABLE("");

/** Creates a new filter of type 'name'.
 The filter's input parameters are set from the dictionary of key-value pairs.
 On OSX, any of the filter input parameters not specified in the dictionary will be undefined.
 On iOS, any of the filter input parameters not specified in the dictionary will be set to default values. */
+ (nullable CIFilter *)filterWithName:(NSString *)name
                  withInputParameters:(nullable CI_DICTIONARY(NSString*,id) *)params NS_AVAILABLE(10_10, 8_0);

2、上面创建滤镜对象时需要filterName,那怎么查看name以及每个CIFilter对象的属性呢?

CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    NSLog(@"%@",filter.attributes);

在上面的代码中输出以下代码

-- :::] {
    "CIAttributeFilterAvailable_Mac" = "10.4";
    ;
    CIAttributeFilterCategories =     (
        CICategoryBlur,
        CICategoryStillImage,
        CICategoryVideo,
        CICategoryBuiltIn
    );
    CIAttributeFilterDisplayName = "Gaussian Blur";
    CIAttributeFilterName = CIGaussianBlur;
    CIAttributeReferenceDocumentation = "http://developer.apple.com/cgi-bin/apple_ref.cgi?apple_ref=//apple_ref/doc/filter/ci/CIGaussianBlur";
    inputImage =     {
        CIAttributeClass = CIImage;
        CIAttributeDescription = "The image to use as an input image. For filters that also use a background image, this is the foreground image.";
        CIAttributeDisplayName = Image;
        CIAttributeType = CIAttributeTypeImage;
    };
    inputRadius =     {
        CIAttributeClass = NSNumber;
        CIAttributeDefault = ;
        CIAttributeDescription = "The radius determines how many pixels are used to create the blur. The larger the radius, the blurrier the result.";
        CIAttributeDisplayName = Radius;
        CIAttributeIdentity = ;
        CIAttributeMin = ;
        CIAttributeSliderMax = ;
        CIAttributeSliderMin = ;
        CIAttributeType = CIAttributeTypeScalar;
    };
}

从上面的输出结果我们可以看到filter有CIAttributeFilterCategories、CIAttributeFilterDisplayName、CIAttributeFilterName、inputImage、inputRadius等属性。

在CIAttributeFilterCategories中可以看到滤镜有CICategoryBlur, CICategoryStillImage,CICategoryVideo, CICategoryBuiltIn种,在CIFilter类中有下面的两个方法能遍历出所有的滤镜名

/** Returns an array containing all published filter names in a category. */
+ (CI_ARRAY(NSString*) *)filterNamesInCategory:(nullable NSString *)category;

/** Returns an array containing all published filter names that belong to all listed categories. */
+ (CI_ARRAY(NSString*) *)filterNamesInCategories:(nullable CI_ARRAY(NSString*) *)categories;

获得到滤镜名之后就可以通过attributes属性查看filter对象的属性 ,通过KVC来设置属性值

 //和UIButton类似 通过简单参数确定CIFilter子类  简单工厂
    CIFilter *filter = [CIFilter filterWithName:@"CIAffineTransform"];
    //  NSLog(@"%@",filter.attributes);
    //将图片输入到滤镜中,打个比方:滤镜是个具有某个功能的容器,任何东西放进去,拿出来的时候就会附上效果。 KVC
    [filter setValue:ciimage forKey:@"inputImage"];
    [filter setValue: [NSValue valueWithCGAffineTransform:CGAffineTransformMakeRotation()] forKey:@"inputTransform"];

4.输出滤镜

1、通过UIImage的imageWithCIImage方法

//从滤镜容器中取出图片  这里还有一种输出方式:使用CIcontext  不知道这两种有什么优缺点,欢迎留言
    //CIImage *new = [filter valueForKey:kCIOutputImageKey];
    CIImage *outputImage = filter.outputImage;

    UIImageView *img = [[UIImageView alloc] initWithFrame:self.view.frame];
    img.image = [UIImage imageWithCIImage:outputImage];
    //img.image=[UIImage imageWithCIImage:outputImage scale:30 orientation:UIImageOrientationDown];
    [self.view addSubview:img];

2、通过通过UIImage的imageWithCGImage方法 此方法要用到CIContext

 //CIImage *new = [filter valueForKey:kCIOutputImageKey];
    CIImage *outputImage = filter.outputImage;

    CIContext *context=[CIContext contextWithOptions:nil];
    CGImageRef cgimg =[context createCGImage:outputImage fromRect:[outputImage extent]];

    UIImageView *img = [[UIImageView alloc] initWithFrame:self.view.frame];
    img.image=[UIImage imageWithCGImage:cgimg];
    [self.view addSubview:img];
    CGImageRelease(cgimg);

上面两种方法中,第一个每次调用都会生成一个CIContext。CIContext本来是可以重用以便提高性能和效率的。

5.完整代码

//
//  ViewController.m
//  CoreImage
//
//  Created by City--Online on 15/11/10.
//  Copyright © 2015年 City--Online. All rights reserved.
//

#import "ViewController.h"
#import <CoreImage/CoreImage.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    CIImage *inputImg = [[CIImage alloc]initWithCGImage:[UIImage imageNamed:@"1.jpg"].CGImage];

    //和UIButton类似 通过简单参数确定CIFilter子类  简单工厂
    CIFilter *filter = [CIFilter filterWithName:@"CIAffineTransform"];

    //输出属性
    NSLog(@"%@",filter.attributes);

    //将图片输入到滤镜中,打个比方:滤镜是个具有某个功能的容器,任何东西放进去,拿出来的时候就会附上效果。 KVC
    [filter setValue:inputImg forKey:@"inputImage"];
    [filter setValue: [NSValue valueWithCGAffineTransform:CGAffineTransformMakeRotation()] forKey:@"inputTransform"];

    //从滤镜容器中取出图片  这里还有一种输出方式:使用CIcontext  不知道这两种有什么优缺点,欢迎留言
    //CIImage *new = [filter valueForKey:kCIOutputImageKey];
    CIImage *outputImage = filter.outputImage;

    //通过CIContext上下文 、imageWithCGImage输出滤镜
    CIContext *context=[CIContext contextWithOptions:nil];
    CGImageRef cgimg =[context createCGImage:outputImage fromRect:[outputImage extent]];

    UIImageView *img = [[UIImageView alloc] initWithFrame:self.view.frame];
    img.image=[UIImage imageWithCGImage:cgimg];
    [self.view addSubview:img];
    CGImageRelease(cgimg);

    //遍历每种滤镜下的滤镜名
    NSLog(@"%@",[CIFilter filterNamesInCategories:@[@"CICategoryBlur"]]);
    NSLog(@"%@",[CIFilter filterNamesInCategories:@[@"CICategoryVideo"]]);
    NSLog(@"%@",[CIFilter filterNamesInCategories:@[@"CICategoryStillImage"]]);
    NSLog(@"%@",[CIFilter filterNamesInCategories:@[@"CICategoryBuiltIn"]]);

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

6.效果

IOS Core Image之一的更多相关文章

  1. 转 iOS Core Animation 动画 入门学习(一)基础

    iOS Core Animation 动画 入门学习(一)基础 reference:https://developer.apple.com/library/ios/documentation/Coco ...

  2. iOS - Core Animation 核心动画

    1.UIView 动画 具体讲解见 iOS - UIView 动画 2.UIImageView 动画 具体讲解见 iOS - UIImageView 动画 3.CADisplayLink 定时器 具体 ...

  3. IOS Core Image之二

    在上篇博客IOS Core Image之一中了解了下CIImage.CIFilter.CIContext三个类的使用,这篇了解下滤镜链(多滤镜)和人脸检测(不是人脸识别). 一.多滤镜 1.有些效果不 ...

  4. iOS Core ML与Vision初识

    代码地址如下:http://www.demodashi.com/demo/11715.html 教之道 贵以专 昔孟母 择邻处 子不学 断机杼 随着苹果新品iPhone x的发布,正式版iOS 11也 ...

  5. iOS Core Animation 简明系列教程

    iOS Core Animation 简明系列教程  看到无数的CA教程,都非常的难懂,各种事务各种图层关系看的人头大.自己就想用通俗的语言翻译给大家听,尽可能准确表达,如果哪里有问题,请您指出我会尽 ...

  6. IOS Core Animation Advanced Techniques的学习笔记(五)

    第六章:Specialized Layers   类别 用途 CAEmitterLayer 用于实现基于Core Animation粒子发射系统.发射器层对象控制粒子的生成和起源 CAGradient ...

  7. IOS Core Animation Advanced Techniques的学习笔记(四)

    第五章:Transforms   Affine Transforms   CGAffineTransform是二维的     Creating a CGAffineTransform   主要有三种变 ...

  8. IOS Core Animation Advanced Techniques的学习笔记(一)

    转载. Book Description Publication Date: August 12, 2013 Core Animation is the technology underlying A ...

  9. iOS Core Animation之CALayer心得

    使用CALayer的mask实现注水动画效果 Core Animation一直是iOS比较有意思的一个主题,使用Core Animation可以实现非常平滑的炫酷动画.Core animtion的AP ...

  10. iOS——Core Animation 知识摘抄(四)

    原文地址http://www.cocoachina.com/ios/20150106/10840.html 延迟解压 一旦图片文件被加载就必须要进行解码,解码过程是一个相当复杂的任务,需要消耗非常长的 ...

随机推荐

  1. (zxing.net)二维码QR Code的简介、实现与解码

    一.简介 二维码QR Code(Quick Response Code)是由Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字 ...

  2. python--内置模块(二) os sys pickle json

    1.os模块 常用方法: os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目 ...

  3. python当中的装饰器

    1.装饰器 首先我们来说一下一个软件的设计原则:开闭原则,又被称为开发封闭原则,你的代码对功能的扩展是开放的,你的程序对修改源代码是封闭的.这样的软件设计思路可以更好的维护和开发. 开放:对功能扩展开 ...

  4. kvm快照备份及常用命令

    转载自:http://www.myjishu.com/?p=431 好文章 kvm快照备份及常用命令 kvm快照,分两种: 1种lvm快照,如果分区是lvm,可以利用lvm进行kvm的快照备份 2种由 ...

  5. java使用Redis4--主从复制

    redis主从复制配置和使用都非常简单.通过主从复制可以允许多个slave server拥有和master server相同的数据库副本.下面是关于redis主从复制的一些特点:       1.ma ...

  6. CentOS 7 Apache服务的安装与配置(转)

    https://blog.51cto.com/13525470/2070375 一.Apache简介 Apache 是一个知名的开源Web服务器.早期的Apache服务器由Apache Group来维 ...

  7. Parallelism VS Concurrency

     一个电脑/手机 有很多核,每一个核上运行一个任务,叫做 Parallelism. 只有一个核,通过任务调度,也可以实现 Concurrency.

  8. 人工鱼群算法超详细解析附带JAVA代码

    01 前言 本着学习的心态,还是想把这个算法写一写,给大家科普一下的吧. 02 人工鱼群算法 2.1 定义 人工鱼群算法为山东大学副教授李晓磊2002年从鱼找寻食物的现象中表现的种种移动寻觅特点中得到 ...

  9. [原创]php任务调度器 hellogerard/jobby

    目录 简介 安装 标准使用 选项 项目实践 简介 一个强大的php层面上的定时任务调度器, 无需修改系统层面的crontab 实际中, php 结合 crontab 来实现定时任务是一种经得住考验的实 ...

  10. 用Jquery获取Url的参数

    在网上找的一个办法 //先写一个方法 function GetUrlString(name) { var reg = new RegExp("(^|&)"+ name +& ...