【Python 实战】---- 实现批量图片的切割

news2025/1/23 2:14:37

1. 需求场景

在实际开发中,我们会遇到一种很无聊,但是又必须实现的需求,就是比如协议、大量的宣传页面、大量的静态介绍页面、或者大量静态页面,但是页面高度很高,甚至高度可能会达到50000px,但是为了渲染友好的需求,因此就需要将图片切小,比如规定高度300px每张,就需要切一百多张图片,可想如果做那种一个省份的每个县城的介绍页面,页面就有几十个,一个页面少的都要切割几十张,多的上百张,是不是一个让人崩溃的需求,但是作为开发人员,我们要学会自己开发一些小工具,让我们从这些无聊,而又不得不实现的需求中解放出来。小工具开发!我曾经遇到的最多的是自己切图,开发四十多个静态介绍页面,当时不会python,切到发吐,有时psd还会卡死,崩溃的一天!

2. 需求实现

  1. 图片切割方法很多,比如 PIL 和 OPENCV,由于我之前学习过 opencv,因此本文采用 opencv 实现;
  2. 获取我们需要切割图片的固定高度;
  3. 需要切割的图片筛选;
  4. 完成对图片的切割;
  5. 保存切割好的图片。

3. 需要切割图片预览

输入图片说明

4. 筛选需要切割的图片

  1. 获取路径下的所有文件;
  2. 筛选其中的图片文件,返回图片名称列表。
# 获取文件夹下所有图片文件名称
def get_all_image_names(path):
  # 获取路径下的所有文件
  names = os.listdir(path)
  # 筛选其中的图片文件,返回图片名称列表
  image_names = list(filter(lambda x : x.split('.').pop() in ['jpg', 'png', 'jpeg', 'bmp'], names))
  return image_names

5. 单个图片切割

  1. 获取需要切割图片的固定高度;
  2. 所需要切割图片的存放路径;
  3. 切割后图片的存放位置;
  4. 读取全部需要切割的图片名称;
  5. 循环获取图片名称;
  6. 单独获取图片名称;
  7. 单独处理当前需要切割图片。
if __name__ == "__main__":
  # 获取需要切割图片的固定高度
  init_img_h = int(input("请输入切割图片的固定高度:"))
  # 所需要切割图片的存放路径
  path = './images'
  # 切割后图片的存放位置
  if not os.path.exists(f'./out_images/'):
    os.makedirs(f'./out_images/')
  # 读取全部需要切割的图片名称
  images = get_all_image_names(path)
  # 循环获取图片名称
  for name in images:
    # 单独获取图片名称
    key_name = name.split('.')[0]
    # 单独处理当前需要切割图片
    handle_single_image(f'{path}/{name}', init_img_h, key_name)

6. 图片处理

  1. 读取图片,获取图片的宽高;
  2. 根据固定高度和图片高度计算需要切割的图片张数;
  3. 计算切割图片的结束Y坐标;
  4. 如果计算的结束坐标大于图片高度,直接使用图片高度作为结束坐标;
  5. 调用opencv的切割封装方法,获取切割后的图片对象;
  6. 保存切割后的图像。
# 处理切割单张图片
def handle_single_image(path, init_img_h, key_name):
  # 读取图片,获取图片的宽高
  img = cv.imread(path)
  h,w,c = img.shape
  # 根据固定高度和图片高度计算需要切割的图片张数
  for val in range(math.ceil(h / init_img_h)):
    # 计算切割图片的结束Y坐标
    end_h = (val + 1) * init_img_h
    # 如果计算的结束坐标大于图片高度,直接使用图片高度作为结束坐标
    if end_h > h:
      end_h = h
    # 调用opencv的切割封装方法,获取切割后的图片对象
    crop_img = crop_image(img, 0, val * init_img_h, w, end_h)
    # 保存切割后的图像
    cv.imwrite(f"./out_images/{key_name}{'%05d'%val}.png",crop_img)

7. 切割封装

# 切割图片
def crop_image(img,startX,startY,endX,endY):
  # 根据传入的坐标值,进行图像切割
  crop_img = img[startY:endY, startX:endX]
  return crop_img

8. 完整代码

import cv2 as cv
import os
import math

# 获取文件夹下所有图片文件名称
def get_all_image_names(path):
  # 获取路径下的所有文件
  names = os.listdir(path)
  # 筛选其中的图片文件,返回图片名称列表
  image_names = list(filter(lambda x : x.split('.').pop() in ['jpg', 'png', 'jpeg', 'bmp'], names))
  return image_names

# 处理切割单张图片
def handle_single_image(path, init_img_h, key_name):
  # 读取图片,获取图片的宽高
  img = cv.imread(path)
  h,w,c = img.shape
  # 根据固定高度和图片高度计算需要切割的图片张数
  for val in range(math.ceil(h / init_img_h)):
    # 计算切割图片的结束Y坐标
    end_h = (val + 1) * init_img_h
    # 如果计算的结束坐标大于图片高度,直接使用图片高度作为结束坐标
    if end_h > h:
      end_h = h
    # 调用opencv的切割封装方法,获取切割后的图片对象
    crop_img = crop_image(img, 0, val * init_img_h, w, end_h)
    # 保存切割后的图像
    cv.imwrite(f"./out_images/{key_name}{'%05d'%val}.png",crop_img)

# 切割图片
def crop_image(img,startX,startY,endX,endY):
  # 根据传入的坐标值,进行图像切割
  crop_img = img[startY:endY, startX:endX]
  return crop_img

if __name__ == "__main__":
  # 获取需要切割图片的固定高度
  init_img_h = int(input("请输入切割图片的固定高度:"))
  # 所需要切割图片的存放路径
  path = './images'
  # 切割后图片的存放位置
  if not os.path.exists(f'./out_images/'):
    os.makedirs(f'./out_images/')
  # 读取全部需要切割的图片名称
  images = get_all_image_names(path)
  # 循环获取图片名称
  for name in images:
    # 单独获取图片名称
    key_name = name.split('.')[0]
    # 单独处理当前需要切割图片
    handle_single_image(f'{path}/{name}', init_img_h, key_name)

9. 切割结果

输入图片说明

10. 总结

  1. 还可以将生成静态页面的代码,创建一个函数,集成进来,这样就能直接一下将几十个页面全部完成,由于不同需求,开发页面不同,因此此处没有进行集成。
  2. 最开始的方案是给定切割张数,然后计算每张的高度,但是这个方案有个问题,就是计算出来的高度是浮点数,因此存在很多精确度的问题,前后两张图片之间会拼接不对等,因此采用固定高度方案,小于固定高度时,使用剩余的作为高度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1007016.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手动开发-实现SpringMVC底层机制--小试牛刀

文章目录 前端控制器Controller注解RequestMapping注解自定义容器LingWebApplicationContext设计handlerList完成分发请求Service注解和AutoWired注解RequestParam注解完整代码 在这里说的底层机制的实现主要是指:前端控制器、Controller、Service注入容器、对象自动…

对话式人工智能的数据采集方案

基于噪声数据训练对话式人工智能 聊天机器人、虚拟助手、机器人等对话式人工智能 (Conversational AI Agents ) 在我们的日常生活中已随处可见。许多企业希望以更低的成本增强与客户之间的互动,并为此在该领域进行大量投资。大量数据表明,对话式人工智能…

泛型工具类型和操作符

前言 TypeScript 内置了一些常用的工具类型。 PartialRequiredOmitPick.... 操作符 typeof typeof 操作符可以用来获取一个变量声明或对象的类型 const p {x:2,y:cm} let g:typeof p {x:3,y:ff} 这里g需要满足: 有x属性且值是number类型 有y属性且值是string类型…

海鲜进口一站式数字化管理,提高工作效率

2022年,中国水产品进口国top10有:厄瓜多尔(主要品种为白虾、剑鱼、沙丁鱼、金枪鱼等)、俄罗斯(主要品种为鳕鱼、鲑鱼、鲱鱼等)、越南(主要品种为巴沙鱼、冻虾等)、印度(主…

认识HTTP请求

要分析HTTP请求和响应必然少不了抓包工具,关于抓包工具的设置和下载推荐看抓包工具Fiddler的下载与设置 通过抓包得到的一个HTTP请求 HTTP请求的格式 结构分析 一.请求行 1.post是方法,可以表示一条HTTP请求要进行的操作是什么,post通常表示…

使用终端MobaXterm连接Centos

1. 下载MobaXterm 官网: https://mobaxterm.mobatek.net/download.html 2. MobaXterm连接Linux 1 、查看刚才安装的 Linux 的 IP 地址 2、连接 3. Linux自带了JRE 由于javac指令不能运行,所以Linux只自带了JRE!!!

【C++】- set和map的具体使用(multiset和multimap的介绍)

💖作者:小树苗渴望变成参天大树🎈 🎉作者宣言:认真写好每一篇博客💤 🎊作者gitee:gitee✨ 💞作者专栏:C语言,数据结构初阶,Linux,C 动态规划算法🎄 如 果 你 …

error:Failed building wheel for XXX

解决方案适用于大多数的pip 安装时出现的Failed building wheel for XXX 出现问题 按以往快速安装包的经验,第一反应当然是使用简单又快捷的terminal命令加上镜像,如下: pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple结…

群晖Cloud Sync数据同步到百度云、另一台群晖、nextcloud教程

群晖Cloud Sync数据同步到百度云、另一台群晖、nextcloud教程 一、群晖套件中下载Cloud Sync 二、同步到百度云盘 打开Cloud Sync,点击左上角的号,云供应商选择百度云。 这里可以选择双向备份,也可以只上穿到百度云的仅上传本地更改。因为百…

D盘无法格式化?3个方法!轻松解决问题!

“我的电脑d盘好像中病毒了,我想将它格式化但是每次操作都显示d盘无法格式化。这是为什么呢?我应该怎么解决?” 有时候,我们的电脑可能会出现一些问题,导致我们不得不将某些磁盘进行格式化操作。这时候问题就出现了。有…

CSP 202005-1 重复局面

题目背景 国际象棋在对局时,同一局面连续或间断出现3次或3次以上,可由任意一方提出和棋。 问题描述 国际象棋每一个局面可以用大小为 的字符数组来表示,其中每一位对应棋盘上的一个格子。六种棋子王、后、车、象、马、兵分别用字母 k、q、…

Polarion导入需求(Word)

简介 将需求文档导入Polarion并实现自动创建工作项具有多个优势,这些优势有助于提高项目管理和协作的效率,以下是一些主要的优势点:减少手动工作: 自动创建工作项可以显著减少手动数据输入的工作量。不再需要手动逐一创建每个工作…

聚类-kmeans

聚类算法是无监督学习算法,指定将数据分成k个簇。然后通过每个点到各个簇的中心的欧氏距离来分类。 kmeans本身会陷入局部最小值的状况,二分kmeans可以解决这一点。 二分kmeans是遍历所有的簇,将其分成2个,比较哪一个分裂结果更…

2023年7月京东休闲食品行业品牌销售排行榜(京东大数据)

鲸参谋监测的京东平台7月份休闲食品市场销售数据已出炉! 根据鲸参谋平台的数据显示,7月份休闲食品市场整体呈现下滑趋势。当月休闲食品在京东平台的销量为3400万,环比下降约26%,同比下降约26%;销售额将近11亿&#xf…

Equall Apple 的革命性变压器:一个宽幅前馈,实现前所未有的效率和精度

变压器架构已显示出显著的可扩展性,从而大大提高了精度。然而,这种进步是以极高的计算要求为代价的,这已成为实际应用中的重大障碍。 尽管研究人员一直在积极寻求解决方案来减小变压器组件的尺寸并修剪注意力头等元素,但另一个关…

自动化测试01

测试脚本编写参考 selenium IDE 插件,firefox浏览器搜索安装,(无法安装) katalon recorder 负责输出脚本,输出模式,python2unitest , 无法输出python3类型脚本,仅参考 开发者工具 …

Ubuntu安装Android Studio

一、Android Studio安装 官方教程:安装 Android Studio | Android Developers 1、下载:Download Android Studio & App Tools - Android Developers,选择linux版本 2、 提取/解压 将下载的安装包提取出来 3、 64位ubuntu系统&#…

三分钟创建扫码查分系统

学生考试的成绩是家长和学生关注的重要问题。传统的成绩查询方式往往需要将整个成绩表格发到群里,不仅操作繁琐,而且可能导致信息泄露。为了解决这个问题,易查分应运而生。易查分是一个可以将Excel表格转换为在线查询的工具,可以轻…

Python——操作MySQL数据库

😊Python——操作MySQL数据库 🚀前言🔍数据库编程🍭数据库编程基本介绍🍭数据库编程接口🍭什么情况下会使用Python操作MySQL数据库?🍭Java和Python操作MySQL数据库有何不同&#xff…

基于Python开发的AI智能联系人管理程序(源码+可执行程序+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python开发的AI智能联系人管理程序,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含:项目源码、项目文档等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#…