吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2512|回复: 4
收起左侧

[Python 转载] 用python制作单页照片墙

  [复制链接]
subney 发表于 2021-6-29 19:04

需求:手上有几百张图片,如果要展示,最好是生成缩略图,而不是给原图。但是几百张缩略图看起来也累,最好一图搞定。
方法:借用Python PIL库。

from PIL import Image
import os
from collections import namedtuple

#快速创建一个数据类
Canvas=namedtuple('Canvas',['row','column','image'])

#把传进来的文件列表筛选一下,排除非图片文件
def __filter_images(files:list,image_types:list)->list:
  images=[]
  for file in files:
    extension=os.path.splitext(file)[-1].lower()
    #这一步写地丑了
    for t in image_types:
      if t in extension:
        images.append(file)
        break
  return images

#根据参数创建一张空白图片
def __create_canvas(images_count,thunmb_size,max_width,gap):
  columns=1
  canvas_width=0
  calc_width=lambda col: col*thunmb_size[0] + (col-1)*gap
  #一点点增加列数,直到接近最大图片宽度
  while True:
    canvas_width=calc_width(columns)
    if canvas_width>max_width:
      break
    columns+=1
  #最后要回退一列
  columns-=1
  canvas_width=calc_width(columns)
  #同样的方式,计算图片高度
  rows=1
  while rows*columns<images_count:
    rows+=1
  #回退一行高度
  canvas_height=rows*thunmb_size[1]+(rows-1)*gap
  canvas=Image.new('RGB',(canvas_width,canvas_height))
  return Canvas(rows,columns,canvas)

#生成素材图片的缩略图
def __createThunmbnail(image:Image.Image,thumb_size):
  #主要工作是保持图片原有宽高比例的情况下
  #生成比指定size小的小图
  #这里可以改进,根据不同的模式:cover、stretch等处理图片
  width,height=image.size
  scale_x=width/thumb_size[0]
  scale_y=height/thumb_size[1]
  if scale_x>scale_y:
    width=thumb_size[0]
    height=height/scale_x
  else:
    height=thumb_size[1]
    width=width/scale_y
  image.thumbnail((width,height))
  return image

#将小图片粘贴到合成图中
def __paste_thumbnail(target:Image.Image,source:Image.Image,row:int,column:int,thumb_size,gap):
  #计算位置的左边界
  left=column*(thumb_size[0]+gap)
  #计算位置的上边界
  top=row*(thumb_size[1]+gap)
  #因为小图的尺寸不一样,需要在格子中居中
  offset_x,offset_y=0,0
  if source.size[0]<thumb_size[0]:
    offset_x=(thumb_size[0]-source.size[0])//2

  if source.size[1]<thumb_size[1]:
    offset_y=(thumb_size[1]-source.size[1])//2

  target.paste(source,(left+offset_x,top+offset_y))
  return target

#生成大图的主函数
#folder:图片目录
#thumbSize:小图的最大尺寸
#max_width:大图的最大宽度
#gap:小图之间的默认间距
#image_types:筛选图片格式的列表
def generateThumnnail(folder,thunmbSize=(256,256),max_width=1080,gap=10,image_types=['gif','jpg','png'])->Image.Image:
  #读取图片素材
  images=__filter_images(os.listdir(folder),image_types)
  #因为python读取的文件不包含目录部分,需要重新合成完整路径
  images=[os.path.join(folder,image) for image in images] 
  #生成空白大图
  row,column,blank_image=__create_canvas(len(images),thunmbSize,max_width,gap)
  #迭代图片素材的序号
  index=0
  for r in range(row):
    for c in range(column):
      #行列相乘的结果可能大于素材总数,所以需要判断一下
      if index>=len(images):
        return blank_image
      #加载素材图
      raw=Image.open(images[index])
      #得到小图
      thumb=__createThunmbnail(raw,thunmbSize)
      #把小图贴到大图的相应位置
      __paste_thumbnail(blank_image,thumb,r,c,thunmbSize,gap)
      index+=1
      # print(r,c,index)
  return blank_image

素材图文件夹如下:
Snipaste_2021-06-29_18-58-22.jpg
成品如下:原图太大,一压缩,效果赶上打码了……
蜂蜜浏览器_1.jpg
存在的问题:小图之间的空白太难看,一时想不到好的排列算法。暴力算法都头疼。
还有一个问题:我好像见过实现这个功能的软件,那这轮子造的可太糙了{:1_907:}

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
simile088 + 1 + 1 谢谢@Thanks!
shou0823 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

cs7392000 发表于 2021-6-29 19:07
感谢楼主分享
fanvalen 发表于 2021-6-29 20:11
我记得好像有个排序的,但是一时想不起叫什么名字了,
就是很多文字围绕一个关键词在周围环绕,关键词还特别大周围的小
算了算了
树洞先生 发表于 2021-6-29 20:22
CollageIt   楼主可以试试这个  不过还是感谢你的分享
 楼主| subney 发表于 2021-6-30 09:34
fanvalen 发表于 2021-6-29 20:11
我记得好像有个排序的,但是一时想不起叫什么名字了,
就是很多文字围绕一个关键词在周围环绕,关键词还特 ...

难道是词云?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 16:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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