网页技术交流
 
发新帖
楼主: 零五零八
查看: 808|回复: 0

[使用教程] python图片合成的示例

[复制链接]
零五零八 发表于 2020-11-10 10:53:58 | 显示全部楼层
本帖最后由 零五零八 于 2020-11-10 11:01 编辑

   这里用我半个月前看到的一篇博客写的demo作为背景,做一下图片的合成图片可以看作是很多像素点组成的,每个像素点都是一个RGB颜色,(red, green, blue), 那么合成两张照片就有办法了,我们可以在一张新的RGB色的图片里一个像素点取图片一的对应位置的像素,下一个像素点取图片二的像素,直到遍历完成,代码如下:


  1. from PIL import Image

  2. ##这里采用传入图片地址调用此函数

  3. #这个方法目前不支持按比例合成,默认为1:1
  4. #各取一个像素点合并,传入的参数为两张图片的地址
  5. def merge1(img1_address,img2_addess):
  6. status=100
  7. #状态码100为正常
  8. #  200为地址错误
  9. try:
  10.   img1=Image.open(img1_address)
  11.   img2=Image.open(img2_address)
  12. except:
  13.   status=200
  14.   img_new=""
  15. else:
  16.   width=min(img1.size[0],img2.size[0])
  17.   height=min(img1.size[1],img2.size[1])
  18.   print(width,height)
  19.   img_new = Image.new('RGB',(width,height))
  20.   for x in range(width):
  21.    for y in range(height):
  22.     if y%2==0:
  23.      pixel=img1.getpixel((x,y))
  24.      img_new.putpixel((x,y),pixel)
  25.     else:
  26.      pixel=img2.getpixel((x,y))
  27.      img_new.putpixel((x,y),pixel)
  28. finally:
  29.   return img_new,status
复制代码


   上述代码会返回一张新的图片和一个状态码,接受的时候用两个变量接受另一种方法是每个像素点各取%50的原图片的颜色,然后把像素点放置在对应位置,为了功能更加强大,我把两者的混合比例设为可调,默认是50%的比例,代码如下:




  1. from PIL import Image

  2. #将像素点按比例取色,然后合成一个新像素点
  3. #传入的参数为两张图片的地址和比例
  4. #如果两者之和不为1则以第一个图片的比例为准
  5. def merge2(img1_address,img2_address,percent1=0.50,percent2=0.50):
  6. status=100
  7. #状态码100为正常
  8. #  200为地址错误
  9. try:
  10.   img1=Image.open(img1_address)
  11.   img2=Image.open(img2_address)
  12. except:
  13.   status=200
  14.   img_new=""
  15. else:
  16.   if percent1+percent2!=1:
  17.    percent2=1-percent1
  18.   width = min(img1.size[0],img2.size[0])
  19.   height = min(img1.size[1],img2.size[1])
  20.   img_new = Image.new('RGB',(width,height))
  21.   for x in range(width):
  22.    for y in range(height):
  23.     r1,g1,b1=img1.getpixel((x,y))
  24.     r2,g2,b2=img2.getpixel((x,y))
  25.     r=int(percent1*r1+percent2*r2)
  26.     g=int(percent1*g1+percent2*g2)
  27.     b=int(percent1*b1+percent2*b2)
  28.     img_new.putpixel((x,y),(r,g,b))
  29. finally:
  30.   return img_new,status
复制代码

返回的参数与上述相同  如果想要保存图片可用image.save()函数保存
总的代码如下:


  1. from PIL import Image

  2. ##这里采用传入图片地址调用此函数

  3. #这个方法目前不支持按比例合成,默认为1:1
  4. #各取一个像素点合并,传入的参数为两张图片的地址
  5. def merge1(img1_address, img2_addess, direct):
  6. status=100
  7. #状态码100为正常
  8. #  200为地址错误
  9. try:
  10.   img1=Image.open(img1_address)
  11.   img2=Image.open(img2_address)
  12. except:
  13.   status=200
  14.   img_new=""
  15. else:
  16.   width=min(img1.size[0], img2.size[0])
  17.   height=min(img1.size[1], img2.size[1])
  18.   print(width,height)
  19.   img_new = Image.new('RGB',(width, height))
  20.   for x in range(width):
  21.    for y in range(height):
  22.     if y%2 == 0:
  23.      pixel = img1.getpixel((x,y))
  24.      img_new.putpixel((x,y), pixel)
  25.     else:
  26.      pixel = img2.getpixel((x,y))
  27.      img_new.putpixel((x,y), pixel)
  28. finally:
  29.   return status

  30. #将像素点按比例取色,然后合成一个新像素点
  31. #传入的参数为两张图片的地址和比例
  32. #如果两者之和不为1则以第一个图片的比例为准
  33. def merge2(img1_address, img2_address, direction, percent1):

  34. status = 100
  35. #状态码100为正常
  36. # 200为地址错误
  37. try:
  38.   img1 = Image.open(img1_address)
  39.   img2 = Image.open(img2_address)
  40. except:
  41.   status = 200
  42.   img_new = ""
  43. else:
  44.   percent2 = 1 - percent1
  45.   width = min(img1.size[0], img2.size[0])
  46.   height = min(img1.size[1], img2.size[1])
  47.   img_new = Image.new('RGB', (width,height))
  48.   for x in range(width):
  49.    for y in range(height):
  50.     r1,g1,b1=img1.getpixel((x,y))
  51.     r2,g2,b2=img2.getpixel((x,y))
  52.     r = int(percent1 * r1 + percent2 * r2)
  53.     g = int(percent1 * g1 +percent2 * g2)
  54.     b = int(percent1 * b1 +percent2 * b2)
  55.     img_new.putpixel((x,y),(r,g,b))
  56.   img_new.save(direction)
  57.   #img_new.show()
  58. finally:
  59.   return status
  60. #切记在接受返回信息时先判断状态码是否异常,如果正确再执行相应操作
  61. if __name__=='__main__':

  62. img1_address = "B:\Picture\YourName\1.jpg"
  63. img2_address = "B:\Picture\YourName\2.jpg"
  64. direction = "D:/Python/PyQt/课程设计/merges/merge9.png"
  65. status = merge2(img1_address, img2_address, direction, 0.30)
  66. print(status)
复制代码


  当然,我发现Image库中有Image.blend(image1, image2, alpha)这个混合图片的函数,还没看源码,不知道他是用什么方法实现的。
原先的两张照片:


1.png


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


优劣:
      方法一:不易造成曝光过度,因为实际的像素点并没改动,只是间隔变大了,                       但这样可能会造成轮廓不清晰



      方法二:在比例适当时效果是优于方式一的,但比例不合适就会看起来像曝光过度一样,                   示例中方法二用的比例是0.3:0.7,又是比例不当效果会很糟糕,孰优孰劣请按效果好坏使用。











快速回复 返回顶部 返回列表