使用swift制作简易图片滤镜

图片是由许多像素组成的,每个像素都有r,g,b,a4个值。如果对像素的这些值进行改变,就会改变像素的颜色或透明度。

对整个图片的像素进行有选择的改变就能改变整个图片的现实效果(图片滤镜)

首先要确定,rgba值的数据格式是UInt8,不能随意和Int值进行计算,因此在一些求平均值的情况要先将rgba用Int()将这些值转换为int再计算。

源码地址:https://github.com/lsvih/ImageProcessor

首先读取图片

1
let image = UIImage(named: "sample")

运行结果:

upload successful

写一个滤镜,用于在遍历像素时去掉照片中所有的红色

1
2
3
4
func removeRed(var pixel: Pixel) ->Pixel{
pixel.red = 0
return pixel
}

上述函数的作用为将每个读取到的像素的red值设为0之后再返回。

测试一下这个滤镜:

1
2
3
4
5
6
7
8
9
10
11
func testRemoveRedFilter(image: UIImage) -> UIImage {
var thisImage = RGBAImage(image: image)!
for y in 0..<thisImage.height {
for x in 0..<thisImage.width {
let sub = y * thisImage.width + x
let pixel = thisImage.pixels[sub]//遍历每个像素
thisImage.pixels[sub] = removeRed(pixel)
}
}
return thisImage.toUIImage()!
}

上述函数作用为遍历图片中的每一个像素,应用上面取出红色的函数后,将像素返回图片。最终得到了如下图片:

upload successful

根据这个原理,可以进行各种滤镜的编写。

1、去除指定颜色

1
2
3
4
5
6
7
8
9
10
func removeColor(var pixel:Pixel,conf:Int) -> Pixel{
if(conf == 0){
pixel.red = 0
}else if(conf == 1){
pixel.green = 0
}else if(conf == 2){
pixel.blue = 0
}
return pixel
}

传值0为去除红色,1为去除绿色,2为去除蓝色

运行结果如下

upload successful

2、灰度图

1
2
3
4
5
6
7
func grayScale(var pixel:Pixel,conf:Int)->Pixel{
let gray = UInt8((Int(pixel.red)+Int(pixel.green)+Int(pixel.blue))/conf)
pixel.red = gray
pixel.green = gray
pixel.blue = gray
return pixel
}

conf可以控制图片灰度,通常为3.对每个像素把他们的rgb值求平均值,这个像素就变成相应的灰色了。

运行结果如下

upload successful

3、更改透明度

像素rgba中的a值即为透明度,改变a值照片的透明度将发生变化

1
2
3
4
func transparentFilter(var pixel:Pixel,opacity:Int)->Pixel{
pixel.alpha = UInt8(opacity)
return pixel
}

由于a为UInt8,因此需要转换。输入的opacity为透明度,从0-255

效果如下

upload successful

4、黑白照片

定义一个阀值,rgb平均值超过这个阀值的为白否则为黑

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
func blackAndWhite(var pixel:Pixel,conf:Int)->Pixel{
if(conf==1){
let avg = UInt8((Int(pixel.red)+Int(pixel.green)+Int(pixel.blue))/3)
if(avg>100){
pixel.red = 255
pixel.green = 255
pixel.blue = 255
}else{
pixel.red = 0
pixel.green = 0
pixel.blue = 0
}
}else{
let avg = UInt8((Int(pixel.red)+Int(pixel.green)+Int(pixel.blue))/3)
if(avg<100){
pixel.red = 255
pixel.green = 255
pixel.blue = 255
}else{
pixel.red = 0
pixel.green = 0
pixel.blue = 0
}

}
return pixel
}

传值conf为0时生成黑白图片,如果为1则反色

效果如下

upload successful

5、反相

用255减去rgb值即为反相效果

1
2
3
4
5
6
func inverseColor(var pixel:Pixel,conf:Int)->Pixel{
pixel.red = min(max(UInt8(conf) - pixel.red,0),255)
pixel.green = min(max(UInt8(conf) - pixel.green,0),255)
pixel.blue = min(max(UInt8(conf) - pixel.blue,0),255)
return pixel
}

要对减法得到的值进行约束防止出现负数。

效果如下

upload successful