GPUImage(三)快速搞定自定义滤镜

快速搞定自定义滤镜

GPUImage中提供了GPUImageLookupFilter这样一个滤镜。可以大大的减少滤镜的开发时间。
GPUImageLookupFilter通过一个颜色映射表来实现颜色转换。这种查表法的原理就是在一张表中为每种颜色纪录一个对应的映射目标的颜色。当用查表法对一张照片做颜色映射时,只需要遍历照片的每个像素点,然后在表中找到该像素颜色对应的目标颜色,最后将该像素设置为目标颜色即可。查表法实现的前提是颜色的映射与周围的颜色无关,即一种颜色无论周围的颜色为何、无论其位于照片的哪个位置,其目标颜色都应该是相同的。

RGB的颜色数量表示为2552552555 = 16777216如果要记录每种颜色的映射结果,那么需要一千六百多万条记录,这显然无法应用到实际的工程中。为了简化起见,一般每相近的 4 种颜色采用一条记录存储,这样颜色表只需要 646464 = 262144 条记录。
下面是一张标准的基准颜色表

设计师或产品经理在PS中调整好的效果可能是这样的一组Action

将这些调整应用到基准颜色表上就得到了一张映射表

上表将 262144 种颜色分为 8 个块,每块64*64格,每一格的颜色都不同。进行颜色映射时,首先使用数字图像处理软件对该基准颜色表应用要模拟的滤镜来生成映射表(如下图),然后对要处理的照片的每个像素,从基准颜色表中找到该像素颜色的位置,然后在映射表的相应位置就可以得到目的颜色。

暗角可以使用遮罩的方式(也就是使用png图片)也可以使用这个滤镜GPUImageVignetteFilter

下面是demo code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 -(UIImage *)p_ImageFilterWithFilterName:(NSString *)filterName originImage:(UIImage *)originImage{
2
3 GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:originImage];
4 GPUImagePicture *lookupImageSource = [[GPUImagePicture alloc] initWithImage:[UIImage imageNamed:filterName]];
5 GPUImageLookupFilter *lookupFilter = [[GPUImageLookupFilter alloc] init];
6
7 [stillImageSource addTarget:lookupFilter];
8 [lookupImageSource addTarget:lookupFilter];
9 if (self.hasVignetteEffect) {
10 [lookupFilter useNextFrameForImageCapture];
11 GPUImageVignetteFilter *vignettefilter = [[GPUImageVignetteFilter alloc] init];
12 vignettefilter.vignetteEnd = kAlohaImageVignetteEnd;
13 vignettefilter.vignetteStart = kAlohaImageVignetteStart;
14
15 [lookupFilter addTarget:vignettefilter];
16 [stillImageSource processImage];
17 [lookupImageSource processImage];
18 [vignettefilter useNextFrameForImageCapture];
19 UIImage *filteredimage = [vignettefilter imageFromCurrentFramebuffer];
20 return filteredimage;
21 } else {
22 [stillImageSource processImage];
23 [lookupImageSource processImage];
24 [lookupFilter useNextFrameForImageCapture];
25 UIImage *filteredimage = [lookupFilter imageFromCurrentFramebuffer];
26 return filteredimage;
27 }
28 }