这篇文章主要介绍了python图片合成的示例,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下
python的PIL库简直好用的不得了,PIL下面的Image库更是封装了很多对图片处理的函数,关于Image库的介绍和使用,
这里用我半个月前看到的一篇博客写的demo作为背景,做一下图片的合成
图片可以看作是很多像素点组成的,每个像素点都是一个RGB颜色,(red, green, blue), 那么合成两张照片就有办法了,我们可以在一张新的RGB色的图片里一个像素点取图片一的对应位置的像素,下一个像素点取图片二的像素,直到遍历完成,代码如下:
|
`from` `PIL` `import` `Image`
`##这里采用传入图片地址调用此函数`
`#这个方法目前不支持按比例合成,默认为1:1`
`#各取一个像素点合并,传入的参数为两张图片的地址`
`def` `merge1(img1_address,img2_addess):`
`status``=``100`
`#状态码100为正常`
`# 200为地址错误`
`try``:`
`img1``=``Image.``open``(img1_address)`
`img2``=``Image.``open``(img2_address)`
`except``:`
`status``=``200`
`img_new``=``""`
`else``:`
`width``=``min``(img1.size[``0``],img2.size[``0``])`
`height``=``min``(img1.size[``1``],img2.size[``1``])`
`print``(width,height)`
`img_new` `=` `Image.new(``'RGB'``,(width,height))`
`for` `x` `in` `range``(width):`
`for` `y` `in` `range``(height):`
`if` `y``%``2``=``=``0``:`
`pixel``=``img1.getpixel((x,y))`
`img_new.putpixel((x,y),pixel)`
`else``:`
`pixel``=``img2.getpixel((x,y))`
`img_new.putpixel((x,y),pixel)`
`finally``:`
`return` `img_new,status`
- 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
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
|
上述代码会返回一张新的图片和一个状态码,接受的时候用两个变量接受
另一种方法是每个像素点各取%50的原图片的颜色,然后把像素点放置在对应位置,为了功能更加强大,我把两者的混合比例设为可调,默认是50%的比例,代码如下:
|
|
`from` `PIL` `import` `Image`
`#将像素点按比例取色,然后合成一个新像素点`
`#传入的参数为两张图片的地址和比例`
`#如果两者之和不为1则以第一个图片的比例为准`
`def` `merge2(img1_address,img2_address,percent1``=``0.50``,percent2``=``0.50``):`
`status``=``100`
`#状态码100为正常`
`# 200为地址错误`
`try``:`
`img1``=``Image.``open``(img1_address)`
`img2``=``Image.``open``(img2_address)`
`except``:`
`status``=``200`
`img_new``=``""`
`else``:`
`if` `percent1``+``percent2!``=``1``:`
`percent2``=``1``-``percent1`
`width` `=` `min``(img1.size[``0``],img2.size[``0``])`
`height` `=` `min``(img1.size[``1``],img2.size[``1``])`
`img_new` `=` `Image.new(``'RGB'``,(width,height))`
`for` `x` `in` `range``(width):`
`for` `y` `in` `range``(height):`
`r1,g1,b1``=``img1.getpixel((x,y))`
`r2,g2,b2``=``img2.getpixel((x,y))`
`r``=``int``(percent1``*``r1``+``percent2``*``r2)`
`g``=``int``(percent1``*``g1``+``percent2``*``g2)`
`b``=``int``(percent1``*``b1``+``percent2``*``b2)`
`img_new.putpixel((x,y),(r,g,b))`
`finally``:`
`return` `img_new,status`
|
- 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
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
返回的参数与上述相同
如果想要保存图片可用image.save()函数保存
总的代码如下:
|
`from` `PIL` `import` `Image`
`##这里采用传入图片地址调用此函数`
`#这个方法目前不支持按比例合成,默认为1:1`
`#各取一个像素点合并,传入的参数为两张图片的地址`
`def` `merge1(img1_address, img2_addess, direct):`
`status``=``100`
`#状态码100为正常`
`# 200为地址错误`
`try``:`
`img1``=``Image.``open``(img1_address)`
`img2``=``Image.``open``(img2_address)`
`except``:`
`status``=``200`
`img_new``=``""`
`else``:`
`width``=``min``(img1.size[``0``], img2.size[``0``])`
`height``=``min``(img1.size[``1``], img2.size[``1``])`
`print``(width,height)`
`img_new` `=` `Image.new(``'RGB'``,(width, height))`
`for` `x` `in` `range``(width):`
`for` `y` `in` `range``(height):`
`if` `y``%``2` `=``=` `0``:`
`pixel` `=` `img1.getpixel((x,y))`
`img_new.putpixel((x,y), pixel)`
`else``:`
`pixel` `=` `img2.getpixel((x,y))`
`img_new.putpixel((x,y), pixel)`
`finally``:`
`return` `status`
`#将像素点按比例取色,然后合成一个新像素点`
`#传入的参数为两张图片的地址和比例`
`#如果两者之和不为1则以第一个图片的比例为准`
`def` `merge2(img1_address, img2_address, direction, percent1):`
`status` `=` `100`
`#状态码100为正常`
`# 200为地址错误`
`try``:`
`img1` `=` `Image.``open``(img1_address)`
`img2` `=` `Image.``open``(img2_address)`
`except``:`
`status` `=` `200`
`img_new` `=` `""`
`else``:`
`percent2` `=` `1` `-` `percent1`
`width` `=` `min``(img1.size[``0``], img2.size[``0``])`
`height` `=` `min``(img1.size[``1``], img2.size[``1``])`
`img_new` `=` `Image.new(``'RGB'``, (width,height))`
`for` `x` `in` `range``(width):`
`for` `y` `in` `range``(height):`
`r1,g1,b1``=``img1.getpixel((x,y))`
`r2,g2,b2``=``img2.getpixel((x,y))`
`r` `=` `int``(percent1` `*` `r1` `+` `percent2` `*` `r2)`
`g` `=` `int``(percent1` `*` `g1` `+``percent2` `*` `g2)`
`b` `=` `int``(percent1` `*` `b1` `+``percent2` `*` `b2)`
`img_new.putpixel((x,y),(r,g,b))`
`img_new.save(direction)`
`#img_new.show()`
`finally``:`
`return` `status`
`#切记在接受返回信息时先判断状态码是否异常,如果正确再执行相应操作`
`if` `__name__``=``=``'__main__'``:`
`img1_address` `=` `"B:\Picture\YourName\1.jpg"`
`img2_address` `=` `"B:\Picture\YourName\2.jpg"`
`direction` `=` `"D:/Python/PyQt/课程设计/merges/merge9.png"`
`status` `=` `merge2(img1_address, img2_address, direction,` `0.30``)`
`print``(status)`
|
- 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
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
当然,我发现Image库中有Image.blend(image1, image2, alpha)这个混合图片的函数,还没看源码,不知道他是用什么方法实现的。
原先的两张照片:
合成后的照片:
左图是方法一,右图是方法二
优劣:
方法一不易造成曝光过度,因为实际的像素点并没改动,只是间隔变大了,但这样可能会造成轮廓不清晰
方法二在比例适当时效果是优于方式一的,但比例不合适就会看起来像曝光过度一样,示例中方法二用的比例是0.3:0.7,又是比例不当效果会很糟糕,孰优孰劣请按效果好坏使用。