本文,转载自:《IOS疯狂讲义》上 使用coreImage滤镜
CoreImage是IOS5的新增框架,通过使用这个框架,我们可以非常容易地对图片进行各种特效处理。包括色彩调节、降噪、扭曲等。简单来说,Core Image 滤镜完全可以与PhotoShop媲美。
Core Image的三个核心API如下。
CIContext:它是CoreImage处理的核心API,所有图片的处理都在它的管理下完成的。
CIFilter:它代表过滤器。所有的过滤器都由该CIFilter代表,在创建CIFilter时需要传入不同的参数即可创建不同类型的过滤器。
CIImage:它代表 Core Image 过滤器处理的图片,CIFilter过滤器的输入图片,输出图片都由该CIImage代表。程序可以通过UIImage、图片文件或像素数据来创建CIImage。
了解了上面的三个核心API之后,接下来即可按如下步骤使用Core Image 执行过滤。在使用Core Image 过滤之前,一定要为项目增加Core Image框架。
1,创建CIContext对象。在IOS平台上有如下三种方式创建CIContext。
第一种方式:创建基于CPU的CIContext对象
ctx =[CIContext contextWithOptions:[NSDictionary dictionaryWithObject[NSNumber numberWithBool:YES] forKey:kCIContextUserSoftwareRenderer]];
第二种方式:创建基于GPU的CIContext对象。
ctx =[CIContext contextWithOptions:nil];
第三种方式:创建基于OpenGL优化的CIcontext对象,可以获得实时性能。
EAGLContext *eaglctx =[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
ctx = [CIContext contextWithEAGLContext:eaglctx];
采用基于GPU的CIContext将可以获得更好的性能,因此,一般建议创建基于GPUde CIcontext,但基于GPU的CIcontext对象无法跨应用访问。比如,应用打开UIImagePickerController选取照片进行美化,如果直接在UIImagePickerControllerDelegate的委托方法里调用CIcontext对象进行处理,那么系统会自动将其降为基于CPU的,速度会变慢,因此,建议委托方法中只把照片保存下来,回到主类里调用CIContext进行处理。
2,创建CIFilter过滤器。CIFilter提供了filterWithName:类方法来创建CIFilter对象。该方法需要传入过滤器的名--Core Image 提供了大量的过滤器,不同的过滤器有不同的名字。 参考文档如下:网址
需要说明的是,并非该文档中列出的所有过滤器都可以在IOS平台上使用,有些过滤器职能在OSX系统上使用。
3,创建CIImage对象,该CIImage将作为过滤器处理的源图片。程序只要调用 CIImage的不同方法,即可通过不同的媒介(如UIImage,图片文件,图片数据等)来创建CIImage对象。
4,调用CIFilter的[filter1 setValue:beginImage forKey:@”inputImage”]方法为inputImage属性赋值,该属性用于指定该过滤器将要处理的源图片。
5,根据需要,为不同的过滤器设置不同的过滤参数。
6,调用CIFilter的outputImage 属性获取该过滤器处理后的图片,程序返回的是CIImage对象。
7,调用CIcontext的不同方法将CIImage转换CGImageRef,或将该CIImage绘制到指定的区域中。
只要经过上面7个步骤,即可使用Core Image的过滤器对图片进行处理。
演示效果如下:
我们发现模糊效果没有实现,我后来仔细看了一下,原因找到了
具体代码如下:
- (void)viewDidLoad
{
[super viewDidLoad];
// 创建UIImagePickerController对象,用于选取照片库的照片
imagePicker = [[UIImagePickerController alloc] init];
// 将UIImagePickerController的委托设self
imagePicker.delegate = self;
self.slider1.minimumValue = 0;
self.slider1.maximumValue = 10;
self.slider2.minimumValue = -4;
self.slider2.maximumValue = 4;
self.slider3.minimumValue = -2 * M_PI;
self.slider3.maximumValue = 2 * M_PI;
self.slider4.minimumValue = 0;
self.slider4.maximumValue = 30;
// 调用reset方法来初始化程序界面。
[self reset:nil];
// 打印所有过滤器信息(仅仅是为了查看)
[self logAllFilters];
// 创建基于CPU的CIContext对象
// ctx = [CIContext contextWithOptions:
// [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
// forKey:kCIContextUseSoftwareRenderer]];
// // 创建基于GPU的CIContext对象
ctx = [CIContext contextWithOptions: nil];
// 创建基于OpenGL优化的CIContext对象,可获得实时性能
// EAGLContext * eaglctx = [[EAGLContext alloc]
// initWithAPI:kEAGLRenderingAPIOpenGLES2];
// ctx = [CIContext contextWithEAGLContext:eaglctx];
// 根据过滤器名来创建过滤器
filter1 = [CIFilter filterWithName:@"CIGaussianBlur"];
filter2 = [CIFilter filterWithName:@"CIBumpDistortion"];
filter3 = [CIFilter filterWithName:@"CIHueAdjust"];
filter4 = [CIFilter filterWithName:@"CIPixellate"];
}
这里展示了三种创建CIContext 对象的方法,大家可以发现名字居然还一样,问题就出在这里了,名字一样,引起了计算机的无法正确的使用这个CIContext对象。修改后的效果,我给大家演示下看看。
修改后的源码下载地址如下:demo