本帖最后由 零五零八 于 2020-11-10 11:01 编辑
这里用我半个月前看到的一篇博客写的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
复制代码
上述代码会返回一张新的图片和一个状态码,接受的时候用两个变量接受另一种方法是每个像素点各取%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
复制代码
返回的参数与上述相同 如果想要保存图片可用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)
复制代码
当然,我发现Image库中有Image.blend(image1, image2, alpha)这个混合图片的函数,还没看源码,不知道他是用什么方法实现的。
原先的两张照片:
左图是方法一,右图是方法二
优劣:
方法一:不易造成曝光过度,因为实际的像素点并没改动,只是间隔变大了, 但这样可能会造成轮廓不清晰
方法二:在比例适当时效果是优于方式一的,但比例不合适就会看起来像曝光过度一样, 示例中方法二用的比例是0.3:0.7,又是比例不当效果会很糟糕,孰优孰劣请按效果好坏使用。
|