0%

使用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
func removeRed(var pixel: Pixel) ->Pixel{
2
    pixel.red = 0
3
    return pixel
4
}

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

测试一下这个滤镜:

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

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

upload successful

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

1、去除指定颜色

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

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

运行结果如下

upload successful

2、灰度图

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

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

运行结果如下

upload successful

3、更改透明度

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

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

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

效果如下

upload successful

4、黑白照片

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

1
func blackAndWhite(var pixel:Pixel,conf:Int)->Pixel{
2
    if(conf==1){
3
        let avg = UInt8((Int(pixel.red)+Int(pixel.green)+Int(pixel.blue))/3)
4
        if(avg>100){
5
            pixel.red = 255
6
            pixel.green = 255
7
            pixel.blue = 255
8
        }else{
9
            pixel.red = 0
10
            pixel.green = 0
11
            pixel.blue = 0
12
        }
13
    }else{
14
        let avg = UInt8((Int(pixel.red)+Int(pixel.green)+Int(pixel.blue))/3)
15
        if(avg<100){
16
            pixel.red = 255
17
            pixel.green = 255
18
            pixel.blue = 255
19
        }else{
20
            pixel.red = 0
21
            pixel.green = 0
22
            pixel.blue = 0
23
        }
24
25
    }
26
    return pixel
27
}

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

效果如下

upload successful

5、反相

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

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

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

效果如下

upload successful