欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > python >内容正文

python

python已知横版求竖版_python3一键排版证件照(一寸照、二寸照),附源代码

发布时间:2024/3/24 python 50 豆豆
生活随笔 收集整理的这篇文章主要介绍了 python已知横版求竖版_python3一键排版证件照(一寸照、二寸照),附源代码 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

又到了一年一度办公园年卡的日子了,每年需要一张一寸照片,库存今年告罄

如果拿着一寸照片去冲印,商家那个冲印的价格可比冲印普通照片不知道贵了多少呗(目测10倍以上)

其实是一样的相纸啊

于是乎,为了省这点钱就自己排版好了

如果选用工具的话,不会ps的推荐“光影魔术手v3.1.2”(最新版感觉不太好用)

but,作为一个技术宅,我当然是选择自己来实现啦!

话不多说,说干就干

思路:

1. 首先需要一张已经拍摄好的证件照,尺寸比例可以不完全按照标准

2. 按比例裁剪(1寸、2寸的比例不同)

3. 缩放到标准尺寸

4. 排版到5寸或者6寸照片上

照片尺寸:宽*高(单位:像素)

1寸照片:295*413

2寸照片:413*626

5寸照片(横版):1500*1050

6寸照片(横版):1800*1200

环境:

python3 + pillow库

具体操作:

1. 裁剪

以1寸照片为例,其高:宽 = 1.4,为了使原始照片不失真,应该按照这个1.4的比例进行裁剪

若大于1.4说明高度多了,需要进行上下裁剪;若小于1.4说明宽度多了,需要进行左右裁剪。这里的裁剪均是对称平均裁剪

Image.crop((left, up, right, below))

参数:

需要四个参数,分别是目标照片的四个边线距离左边和上边的距离

值得注意的是:参数是一个元组,因此看起来有两对括号!

2. 缩放

将已经调整好比例的照片进行标准缩放,标准如下(单位:像素):

1寸照片:295*413

2寸照片:413*626

Image.resize(width, height)

参数:

width:宽

heght:高

3. 排版

先想好冲印5寸照片还是6寸照片,以及是需要1寸、2寸还是混合排版

这两个因素都会影响到排版问题,主要是横or竖的问题

以5寸照片上排版1寸照片为例(5寸横版,1寸竖版,2*4排列),是这样滴:

在排列之前,我细心的用画笔画出了裁剪线,这样手残的人再也不用哆哆嗦嗦剪歪了

bk = Image.new("RGB", [WIDTH_5IN,HEIGHT_5IN], (255,255,255))#创建一个5寸大小的,白色背景的画板

draw = ImageDraw.Draw(bk)#创建画笔

draw.line([(0,HEIGHT_5IN/2),(WIDTH_5IN,HEIGHT_5IN/2)],fill=128) #横线,fill是填充颜色

新建画板就不多讲了,注意一下参数的位置,先宽后高,颜色参数其实有多种写法

这里主要讲一下怎么在画板上画线,其实是需要起点坐标和终点坐标,坐标原点是画板左上角,横轴向右x,纵轴向下y

还是画个图更直观

注意坐标的写法 [(起点x,起点y),(终点x,终点y)],坐标点必须为int类型

我这个画完是这样嘞:

然后就是把照片贴上去,注意要放在每个“格子”的中心呦

Image.paste(photo, (photo左上角坐标))

因此,我们需要计算单个1寸照片在整个画板里左上角坐标,还是画个图说明下:

先求每个小格子里中心点focus_point的坐标,然后根据1寸照片的大小求左上角坐标start_point

然后根据每个start_point循环把照片贴上去就好啦!

我生成的是这样嘞,看起来很完美啊!

同理,5寸照片排版2寸的。这里注意新建画板时候的尺寸,因为相当于是竖版照片

5寸照片混合排列1寸、2寸的:

这里注意一下:

2寸照片旋转了90度,用到的函数中,参数必须写上expand=True

Image.rotate(90,expand=True))

如果没写这个参数默认是False,这样旋转后的照片是按照原来的大小,会有裁剪或者黑边,例如:

6寸照片排版1寸:

6寸照片排版2寸按照5寸照片的排版模式会有高度上的溢出

同理,6寸照片混合排列1寸、2寸的也是有溢出

解决方法:新建画布时候按照6寸比例3:2进行适当的放大,因为冲印的时候也没要求就是标准大小嘛

比如,我将大小改为1950*1300

同理,6寸照片混合排列1寸、2寸的也是有溢出。修改完尺寸,混合排版的样子就多了去了,比如:

源代码:

感觉写的有点啰嗦了,应该使用对象的方法精简一下,很多重复的代码改起来也很麻烦

1 #Author:ZM

2

3 """

4 照片尺寸,宽*高(单位:像素)5 1寸照片:295*4136 2寸照片:413*6267 5寸照片(横版):1500*10508 6寸照片(横版):1800*12009 """

10 from PIL importImage,ImageDraw11

12 WIDTH_1IN = 295

13 HEIGHT_1IN = 413

14

15 WIDTH_2IN = 413

16 HEIGHT_2IN = 626

17

18 WIDTH_5IN = 1500

19 HEIGHT_5IN = 1050

20

21 #非全景6寸照片

22 WIDTH_6IN = 1950

23 HEIGHT_6IN = 1300

24

25 defcut_photo(photo,choice):26 """

27 将照片按照比例进行裁剪成1寸、2寸28 :param photo: 待处理的照片29 :param choice: 1代表1寸,2代表2寸30 :return: 处理后的照片31 """

32 width = photo.size[0] #宽

33 height = photo.size[1] #高

34 rate = height /width35 if choice == 1:36 if rate < (HEIGHT_1IN/WIDTH_1IN):37 x = (width - int(height / HEIGHT_1IN * WIDTH_1IN)) / 2

38 y =039 cutted_photo = photo.crop((x, y, x + (int(height / HEIGHT_1IN * WIDTH_1IN)), y +height))40

41 else:42 x =043 y = (height - int(width / WIDTH_1IN * HEIGHT_1IN)) / 2

44 cutted_photo = photo.crop((x, y, x + width, y + (int(width / WIDTH_1IN *HEIGHT_1IN))))45 returncutted_photo46

47 if choice == 2:48 if rate < (HEIGHT_2IN/WIDTH_2IN):49 x = (width - int(height / HEIGHT_2IN * WIDTH_2IN)) / 2

50 y =051 cutted_photo = im.crop((x, y, x + (int(height / HEIGHT_2IN * WIDTH_2IN)), y +height))52

53 else:54 x =055 y = (height - int(width / WIDTH_2IN * HEIGHT_2IN)) / 2

56 cutted_photo = im.crop((x, y, x + width, y + (int(width / WIDTH_2IN *HEIGHT_2IN))))57

58 returncutted_photo59

60 defresize_photo(photo,choice):61 ‘‘‘

62 缩放照片63 :param photo: 待处理的照片64 :param choice: 1代表1寸,2代表2寸65 :return: 处理后的照片66 ‘‘‘

67 if choice == 1:68 resized_photo =photo.resize((WIDTH_1IN,HEIGHT_1IN))69 returnresized_photo70 if choice == 2:71 resized_photo =photo.resize((WIDTH_2IN, HEIGHT_2IN))72 returnresized_photo73

74

75 deflayout_photo_5_1(photo):76 """

77 在5寸照片上排版1寸照片78 :param photo: 待处理照片1寸79 :return: 处理后的照片80 """

81 bk = Image.new("RGB", [WIDTH_5IN,HEIGHT_5IN], (255,255,255))82 draw = ImageDraw.Draw(bk)#创建画笔

83 draw.line([(0,HEIGHT_5IN/2),(WIDTH_5IN,HEIGHT_5IN/2)],fill=128) #横线

84 draw.line([(WIDTH_5IN*0.25,0),(WIDTH_5IN*0.25,HEIGHT_5IN)],fill=128) #第1条竖线

85 draw.line([(WIDTH_5IN*0.5,0),(WIDTH_5IN*0.5,HEIGHT_5IN)],fill=128) #第2条竖线

86 draw.line([(WIDTH_5IN*0.75,0),(WIDTH_5IN*0.75,HEIGHT_5IN)],fill=128) #第3条竖线

87

88 focus_point = [0.125 * WIDTH_5IN,0.25 *HEIGHT_5IN]89 start_point = [focus_point[0] - 0.5 * WIDTH_1IN, focus_point[1] - 0.5 *HEIGHT_1IN]90 for i in range(0,2):91 for k in range(0,4):92 bk.paste(photo, (int(start_point[0] + (k * WIDTH_5IN / 4)), int(start_point[1] + 0.5 * i *HEIGHT_5IN)))93 returnbk94

95

96 deflayout_photo_5_2(photo):97 """

98 在5寸照片上排版2寸照片99 :param photo: 待处理照片2寸100 :return: 处理后的照片101 """

102 bk = Image.new("RGB", [HEIGHT_5IN,WIDTH_5IN], (255,255,255)) #竖版排版

103 #创建画笔

104 draw =ImageDraw.Draw(bk)105 draw.line([(0,WIDTH_5IN/2),(WIDTH_5IN,WIDTH_5IN/2)],fill=128) #横线

106 draw.line([(HEIGHT_5IN*0.5,0),(HEIGHT_5IN*0.5,WIDTH_5IN)],fill=128) #竖线

107 focus_point = [0.25 * HEIGHT_5IN, 0.25 *WIDTH_5IN]108 start_point = [focus_point[0] - 0.5 * WIDTH_2IN, focus_point[1] - 0.5 *HEIGHT_2IN]109 #print(focus_point,start_point)

110 for i in range(0,2):111 for k in range(0,2):112 bk.paste(photo, (int(start_point[0] + (k * HEIGHT_5IN / 2)), int(start_point[1] + 0.5* i *WIDTH_5IN)))113 returnbk114

115 deflayout_photo_5_mix(photo1,photo2):116 """

117 在5寸照片上混合排版1寸、2寸照片118 :param photo1: 待处理照片1寸119 :param photo1: 待处理照片2寸120 :return: 处理后的照片121 """

122 bk = Image.new("RGB", [WIDTH_5IN,HEIGHT_5IN], (255,255,255))123 #创建画笔

124 draw =ImageDraw.Draw(bk)125 draw.line([(0,HEIGHT_5IN/2),(WIDTH_5IN,HEIGHT_5IN/2)],fill=128) #横线

126 draw.line([(WIDTH_5IN*0.25,0),(WIDTH_5IN*0.25,HEIGHT_5IN)],fill=128) #第1条竖线

127 draw.line([(WIDTH_5IN*0.5,0),(WIDTH_5IN*0.5,HEIGHT_5IN)],fill=128) #第2条竖线

128

129 focus_point = [0.125 * WIDTH_5IN,0.25 *HEIGHT_5IN]130 start_point = [focus_point[0] - 0.5 * WIDTH_1IN, focus_point[1] - 0.5 *HEIGHT_1IN]131 focus_point2 = [0.75 * WIDTH_5IN, 0.25 *HEIGHT_5IN]132 start_point2 = [focus_point2[0] - 0.5 * HEIGHT_2IN, focus_point2[1] - 0.5 *WIDTH_2IN]133

134 for i in range(0,2):135 for k in range(0,2):136 bk.paste(photo1, (int(start_point[0] + (k * WIDTH_5IN / 4)), int(start_point[1] + 0.5 * i *HEIGHT_5IN)))137

138 bk.paste(photo2,(int(start_point2[0]),int(start_point2[1])))139 bk.paste(photo2,(int(start_point2[0]),int(start_point2[1] + 0.5 *HEIGHT_5IN)))140 returnbk141

142 deflayout_photo_6_1(photo):143 """

144 在6寸照片上排版2寸照片145 :param photo: 待处理照片1寸146 :return: 处理后的照片147 """

148 bk = Image.new("RGB", [HEIGHT_6IN,WIDTH_6IN], (255,255,255)) #竖版排版

149 #创建画笔

150 draw =ImageDraw.Draw(bk)151 draw.line([(0,WIDTH_6IN*0.25),(WIDTH_6IN,WIDTH_6IN*0.25)],fill=128) #横线

152 draw.line([(0,WIDTH_6IN*0.5),(WIDTH_6IN,WIDTH_6IN*0.5)],fill=128) #横线

153 draw.line([(0,WIDTH_6IN*0.75),(WIDTH_6IN,WIDTH_6IN*0.75)],fill=128) #横线

154 draw.line([(HEIGHT_6IN*0.25,0),(HEIGHT_6IN*0.25,WIDTH_6IN)],fill=128) #竖线

155 draw.line([(HEIGHT_6IN*0.5,0),(HEIGHT_6IN*0.5,WIDTH_6IN)],fill=128) #竖线

156 draw.line([(HEIGHT_6IN*0.75,0),(HEIGHT_6IN*0.75,WIDTH_6IN)],fill=128) #竖线

157 focus_point = [0.125 * HEIGHT_6IN, 0.125 *WIDTH_6IN]158 start_point = [focus_point[0] - 0.5 * WIDTH_1IN, focus_point[1] - 0.5 *HEIGHT_1IN]159 #print(focus_point,start_point)

160 for i in range(0,4):161 for k in range(0,4):162 bk.paste(photo, (int(start_point[0] + (k * HEIGHT_6IN / 4)), int(start_point[1] + i * 0.25 *WIDTH_6IN )))163 returnbk164

165 deflayout_photo_6_2(photo):166 """

167 在6寸照片上排版2寸照片168 :param photo: 待处理照片2寸169 :return: 处理后的照片170 """

171 bk = Image.new("RGB", [WIDTH_6IN,HEIGHT_6IN], (255,255,255))172 #创建画笔

173 draw =ImageDraw.Draw(bk)174 draw.line([(0,HEIGHT_6IN/2),(WIDTH_6IN,HEIGHT_6IN/2)],fill=128) #横线

175 draw.line([(WIDTH_6IN*0.25,0),(WIDTH_6IN*0.25,HEIGHT_6IN)],fill=128) #第1条竖线

176 draw.line([(WIDTH_6IN*0.5,0),(WIDTH_6IN*0.5,HEIGHT_6IN)],fill=128) #第2条竖线

177 draw.line([(WIDTH_6IN*0.75,0),(WIDTH_6IN*0.75,HEIGHT_6IN)],fill=128) #第3条竖线

178 focus_point = [0.125 * WIDTH_6IN,0.25 *HEIGHT_6IN]179 start_point = [focus_point[0] - 0.5 * WIDTH_2IN, focus_point[1] - 0.5 *HEIGHT_2IN]180 for i in range(0,2):181 for k in range(0,4):182 bk.paste(photo, (int(start_point[0] + (k * WIDTH_6IN / 4)), int(start_point[1] + 0.5 * i *HEIGHT_6IN)))183 returnbk184

185

186 deflayout_photo_6_mix1(photo1,photo2):187 """

188 在6寸照片上混合排版1寸、2寸照片189 :param photo1: 待处理照片1寸190 :param photo1: 待处理照片2寸191 :return: 处理后的照片192 """

193 bk = Image.new("RGB", [WIDTH_6IN,HEIGHT_6IN], (255,255,255))194 #创建画笔

195 draw =ImageDraw.Draw(bk)196 draw.line([(0,HEIGHT_6IN*0.5),(WIDTH_6IN,HEIGHT_6IN/2)],fill=128) #横线

197 draw.line([(0,HEIGHT_6IN*0.25),(WIDTH_6IN*0.5,HEIGHT_6IN*0.25)],fill=128) #短横线

198 draw.line([(0,HEIGHT_6IN*0.75),(WIDTH_6IN*0.5,HEIGHT_6IN*0.75)],fill=128) #短横线

199 draw.line([(WIDTH_6IN*0.25,0),(WIDTH_6IN*0.25,HEIGHT_6IN)],fill=128) #第1条竖线

200 draw.line([(WIDTH_6IN*0.5,0),(WIDTH_6IN*0.5,HEIGHT_6IN)],fill=128) #第2条竖线

201 draw.line([(WIDTH_6IN*0.75,0),(WIDTH_6IN*0.75,HEIGHT_6IN)],fill=128) #第3条竖线

202 focus_point = [0.125 * WIDTH_6IN, 0.125 *HEIGHT_6IN]203 start_point = [focus_point[0] - 0.5 * HEIGHT_1IN, focus_point[1] - 0.5 *WIDTH_1IN]204 for i in range(0,4):205 for k in range(0,2):206 bk.paste(photo1, (int(start_point[0] + (0.25 * k * WIDTH_6IN )), int(start_point[1] + 0.25 * i *HEIGHT_6IN)))207 focus_point2 = [0.625 * WIDTH_6IN, 0.25 *HEIGHT_6IN]208 start_point2 = [focus_point2[0] - 0.5 * WIDTH_2IN, focus_point2[1] - 0.5 *HEIGHT_2IN]209 for i in range(0,2):210 for k in range(0,2):211 bk.paste(photo2,(int(start_point2[0] + (0.25 * k * WIDTH_6IN)), int(start_point2[1] + 0.5 * i *HEIGHT_6IN)))212 bk.show()213 returnbk214

215

216

217 deflayout_photo_6_mix2(photo1,photo2):218 """

219 在6寸照片上混合排版1寸、2寸照片220 :param photo1: 待处理照片1寸221 :param photo1: 待处理照片2寸222 :return: 处理后的照片223 """

224 bk = Image.new("RGB", [HEIGHT_6IN,WIDTH_6IN], (255,255,255)) #竖版排版

225 #创建画笔

226 draw =ImageDraw.Draw(bk)227

228 draw.line([(350,0),(350,WIDTH_6IN)],fill=128) #竖线

229 draw.line([(700,0),(700,WIDTH_6IN)],fill=128) #竖线

230

231

232 draw.line([(0,WIDTH_6IN*0.25),(700,WIDTH_6IN*0.25)],fill=128) #横线1

233 draw.line([(0,WIDTH_6IN*0.5),(700,WIDTH_6IN*0.5)],fill=128) #横线2

234 draw.line([(0,WIDTH_6IN*0.75),(700,WIDTH_6IN*0.75)],fill=128) #横线3

235 draw.line([(700,WIDTH_6IN/3),(HEIGHT_6IN,WIDTH_6IN/3)],fill=128) #横线4

236 draw.line([(700,WIDTH_6IN*2/3),(HEIGHT_6IN,WIDTH_6IN*2/3)],fill=128) #横线5

237

238 focus_point = [0.5 * 350, 0.125 *WIDTH_6IN]239 start_point = [focus_point[0] - 0.5 * WIDTH_1IN, focus_point[1] - 0.5 *HEIGHT_1IN]240

241 #print(focus_point,start_point)

242 for i in range(0,4):243 for k in range(0,2):244 bk.paste(photo1, (int(start_point[0] + (k * 350)), int(start_point[1] + i * 0.25 *WIDTH_6IN )))245

246 focus_point2 = [0.5 * HEIGHT_6IN+350, WIDTH_6IN/6]247 start_point2 = [focus_point2[0] - 0.5 * WIDTH_2IN, focus_point2[1] - 0.5 *HEIGHT_2IN]248 for i in range(0,3):249 bk.paste(photo2, (int(start_point2[0]), int(start_point2[1] + i * WIDTH_6IN /3)))250 returnbk251

252

253 im = Image.open(‘xzk2.jpg‘)254 width =im.size[0]255 height = im.size[1]256 rate = height /width257 layout_photo_5_1(resize_photo(cut_photo(im,1),1)).save(‘5_1.jpg‘)258 layout_photo_5_2(resize_photo(cut_photo(im,2),2)).save(‘5_2.jpg‘)259 layout_photo_6_1(resize_photo(cut_photo(im,1),1)).save(‘6_1.jpg‘)260 layout_photo_6_2(resize_photo(cut_photo(im,2),2)).save(‘6_2.jpg‘)261 layout_photo_5_mix(resize_photo(cut_photo(im,1),1),resize_photo(cut_photo(im,2),2).rotate(90,expand=True)).save(‘5_1_mix.jpg‘)262 layout_photo_6_mix1(resize_photo(cut_photo(im,1),1).rotate(90,expand=True),resize_photo(cut_photo(im,2),2)).save(‘6_mix1.jpg‘)263 layout_photo_6_mix2(resize_photo(cut_photo(im,1),1),resize_photo(cut_photo(im,2),2)).save(‘6_mix2.jpg‘)

最后,感谢薛老板友情出镜!

原文:https://www.cnblogs.com/aby321/p/11805789.html

总结

以上是生活随笔为你收集整理的python已知横版求竖版_python3一键排版证件照(一寸照、二寸照),附源代码的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。