2022年 11月 9日

python图片合成的示例

这篇文章主要介绍了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)这个混合图片的函数,还没看源码,不知道他是用什么方法实现的。

原先的两张照片:

image.png

合成后的照片:

image.png

左图是方法一,右图是方法二

优劣:
方法一不易造成曝光过度,因为实际的像素点并没改动,只是间隔变大了,但这样可能会造成轮廓不清晰
方法二在比例适当时效果是优于方式一的,但比例不合适就会看起来像曝光过度一样,示例中方法二用的比例是0.3:0.7,又是比例不当效果会很糟糕,孰优孰劣请按效果好坏使用。