Core Image提供了很多滤镜,这里介绍自己开发Core Image滤镜的方法,相信会对一些朋友有用。
本文通过一个例子从头至尾介绍了如何开发一个将彩色图片转换为灰度图片的滤镜,并介绍了滤镜的使用方法。
原文作者是Andy Finnell,他参与了Adobe Fireworks的开发。
原文地址是 http://www.losingfight.com/blog/2007/01/13/grayscale-for-the-greater-good/
我希望建立一个图片滤镜插件,幸运地是,XCode已经自带了一个开发滤镜插件的模板。在XCode菜单中选择File-> New Project… 选择Image Unit Plug-in for Objective-C 模板。
接下来取名为 Grayscale,因为这是这个插件要做的事情:灰度化图片。
现在我们有了一个项目,需要做的第一件事是修改描述属性列表。Description.plst会告诉Core Image滤镜的参数、类别和在哪里能够找到插件的核心。但是需要手工修改。
为了让Core Image能够找到并使用滤镜,我们需要给这个滤镜一个有意义的分类。苹果已经提供了一些预先定义的分类,我们可以从中选择。当然,我们也可以修改默认的CICategoryStylize,比如选为CICategoryColorEffect。
修改之后的Description.plist看起来是这样的:
<key>CIAttributeFilterCategories</key>
<array>
<string>CICategoryColorEffect</string>
<string>CICategoryVideo</string>
<string>CICategoryStillImage</string>
</array>
在Description.plist中最重要的事情是修改滤镜的参数。但是看来我们在这个灰度化滤镜中除了源图片之外,并不需要任何输入参数。默认的Description.plist带有三个参数,因此我们需要删掉最后的两个参数。
这样就差不多了,不过我还是需要修改显示的名称,让这个名称在界面中显示。所以我们还需要修改一下Description.strings文件。
"MyKernelFilter" = "Demo CIKernel Only Filter";
"inputScale" = "Scale";
"inputGreenWeight" = "Green Weight";
由于我们不需要任何用户输入的数据,我们可以不用管后两个字符串:inputScale和inputGreenWeight。MyKernelFilter是我们滤镜的名称,所以我们要把它改为Grayscale。
"MyKernelFilter" = "Grayscale";
这样,滤镜所需的定制修改就做好了。
我们已经设置好所有滤镜所需的资源,我们就该写一些实际的代码了。核心代码是使用Core Image Kernel Language写成的,是一个OpenGL Shading Language的子集。
我们打开MyKernelFilter.cikernel文件,删掉它默认的内容。加入以下的代码:
kernel vec4 grayscaleKernel(sampler image)
{
// Get source pixel
vec4 p = sample(image, samplerCoord(image));
// Calculate the intensity
float intensity = clamp(0.3* p.r + 0.59* p.g + 0.11* p.b, 0.0, 1.0);
// Set the destination pixel based on intensity
return vec4(intensity, intensity, intensity, p.a);
}
函数名叫什么其实没有关系,只要它包含kernel关键字。而kernel在这里表示源图片中像素的颜色值到目标像素的颜色值的关系图。你会注意到它返回四个颜色的矢量(红、绿、蓝和Alpha),并将源图做为唯一参数使用。如果还有其他的参数,他们会跟在image这个参数后面出现,就像在Description.plist文件中写的一样。
上面代码第一行仅仅取出源图的点:
vec4 p = sample(image, samplerCoord(image));
就像之前所述,image是做为参数传入的源文件,samplerCoord()函数返回源图片中像素的坐标。sample()函数会返回图片和坐标的像素值。
第二行计算源图像素点的亮度:
float intensity = clamp(0.3* p.r + 0.59* p.g + 0.11* p.b, 0.0, 1.0);
上面算式有点超出本文希望描述的内容,不过我使用的亮度计算的来源是YIQ颜色模型。为了安全考虑,我强制返回的结果是从0到1之间,因为rgb颜色值的范围就是0到1之间。
最后我返回目标像素的颜色值:
return vec4(intensity, intensity, intensity, p.a);
我只是简单地将颜色值转换为亮度值,这样就会将颜色变为亮度的变化。另外还要注意,我并没有计算alpha通道。
以上就是计算方面的内容。接下来,我们只需要Build这个项目就可以生成这个滤镜了。
在用滤镜做其他事情之前,我们需要先安装它。Core Image会查找一系列位置去获取滤镜,最简单的方法就是我们把滤镜复制到/Library/Graphics/Image Units/目录中。
接下来我们就可以用Quartz Composer或者Core Image Fun House对滤镜进行试验了。Core Image Fun House位于/Developer/Applications/Graphics Tools/目录中。打开程序,选择一个图片,接着点击加号,在Color Effect分类中找到Grayscale滤镜,点击Apply就可以看到这个滤镜产生的效果了。
发表评论