【python】将一组图片中的横图和竖图划分开来

本文介绍了一种使用Python实现的图片自动分类方法,能够将图片按照横图和竖图进行分类并移动到不同文件夹中。该方法利用PIL库读取图片尺寸,并通过多线程提高处理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果展示

在这里插入图片描述

项目场景

很多图片管理器都实现了横图和竖图的分类功能,出于某种需求,我们用pyhon实现一下。将一组图片的横图全部移动到一个文件夹中,竖图划分到另一文件夹中。

图片定义

  • 横图:宽大于或等于长的图片
  • 竖图:宽小于长的图片

项目逻辑

  1. 新建名为widthImage的文件夹,作为宽图的保存路径
import os
os.makedirs('widthImage')
  1. 新建名为heightImage的文件夹,作为长图的保存路径
import os
os.makedirs('heightImage')
  1. 打开图片,并获取长和宽
from PIL import Image
img = Image.open('test.png')
        w, h = img.size
img.close()
  1. 对图片的长、宽作出判断,并分别移动到对应的文件夹
import shutil
if w >= h:
	shutil.move(src, dst)
else:
	shutil.move(src, dst)
  1. 为了更快速的移动,可以采用多线程
import concurrent.futures as cf
tp = cf.ThreadPoolExecutor()
tp.submit(move, name)
tp.shutdown()
  1. 打印进度条
3/5 |████████████        | 任务进度: 60.00% 已用时间: 4.50S 剩余时间: 3.00S
import time

# 主函数
def main(n):
    t1 = time.time()
    for i in range(n):
        time.sleep(1.5)  # 假设每个任务的等待时间是1.5s
        t2 = time.time()
        runTime = t2-t1
        show(i+1, n, runTime)

# 进度条打印函数
def show(num, _sum,  runTime):
    barLen = 20  # 进度条的长度
    perFin = num/_sum
    numFin = round(barLen*perFin)
    numNon = barLen-numFin
    leftTime = (1-perFin)*(runTime/perFin)
    print(
        f"{num:0>{len(str(_sum))}}/{_sum}",
        f"|{'█'*numFin}{' '*numNon}|",
        f"任务进度: {perFin*100:.2f}%",
        f"已用时间: {runTime:.2f}S",
        f"剩余时间: {leftTime:.2f}S",
        end='\r')
    if num == _sum:
        print()

main(5)

完整代码

# 横图竖图划分.py
import concurrent.futures as cf
from PIL import Image
import shutil
import time
import os
import re


class ImageClassfy(object):
    # 初始化
    def __init__(self):
    	root = os.getcwd() # 获取当前路径
        self.root = root
        self.names = os.listdir(root)
        self.widthImage = os.path.join(root, 'widthImage')
        self.heightImage = os.path.join(root, 'heightImage')
        self.count = 0
        self.pret()

    # 新建长图和宽度的保存文件夹
    def pret(self):
        for i in self.names:
            pattern = re.compile('(.png|.jpg)$')
            if not re.search(pattern, i):
                self.names.remove(i)
        self.sum = len(self.names)
        if not os.path.exists(self.widthImage):
            os.makedirs(self.widthImage)
        if not os.path.exists(self.heightImage):
            os.makedirs(self.heightImage)

    # 移动图片到对应的文件夹
    def move(self, name):
        src = os.path.join(self.root, name)
        img = Image.open(src)
        w, h = img.size
        img.close()
        if w >= h:
            shutil.move(src, self.widthImage)
        else:
            shutil.move(src, self.heightImage)

    # 打印进度条
    def show(self, num, _sum,  runTime):
        barLen = 20  # 进度条的长度
        perFin = num/_sum
        numFin = round(barLen*perFin)
        numNon = barLen-numFin
        leftTime = (1-perFin)*(runTime/perFin)
        print(
            f"{num:0>{len(str(_sum))}}/{_sum}",
            f"|{'█'*numFin}{' '*numNon}|",
            f"任务进度: {perFin*100:.2f}%",
            f"已用时间: {runTime:.2f}S",
            f"剩余时间: {leftTime:.2f}S",
            end='\r')
        if num == _sum:
            print()

    # 主函数
    def main(self):
        tp = cf.ThreadPoolExecutor(32) # 多进程实现,指定进程数为32
        futures = []
        t1 = time.time()
        for name in self.names:
            future = tp.submit(self.move, name)
            futures.append(future)
        for future in cf.as_completed(futures):
            self.count += 1
            t2 = time.time()
            runTime = t2-t1
            self.show(self.count, self.sum, runTime)
        tp.shutdown()


if __name__ == "__main__":
    ImageClassfy().main()

依赖模块

concurrent.futuresshutiltimeosre都是pyhton内置模块,无需安装。

pillow(PIL)是第三方图片处理库,需要安装:

pip install pillow

使用说明

将代码横图竖图划分.py拖拽到图片文件夹中,双击运行即可。(前提是你电脑装有python环境,并安装了上述依赖模块)

引用参考

https://pillow.readthedocs.io/en/stable/
https://docs.python.org/zh-cn/3/library/os.html
https://docs.python.org/zh-cn/3/library/re.html
https://docs.python.org/zh-cn/3/library/shutil.html
https://docs.python.org/zh-cn/3/library/concurrent.futures.html
### 使用Python实现像分割 为了将图片切割成多个小块,可以采用多种方法技术。以下是几种常用的方式以及相应的库。 #### 方法一:使用Pillow库进行简单切割 Pillow是一个非常流行的用于处理像的Python库。通过该库能够轻松地加载、操作并保存各种格式的像文件。下面是一段简单的代码示例来展示如何利用Pillow来进行基本的像切割: ```python from PIL import Image def slice_image(image_path, output_folder, rows=2, cols=2): img = Image.open(image_path) width, height = img.size piece_width = int(width / cols) piece_height = int(height / rows) for row in range(rows): for col in range(cols): box = (col * piece_width, row * piece_height, (col + 1) * piece_width, (row + 1) * piece_height) cropped_img = img.crop(box) save_name = f"{output_folder}/slice_{row}_{col}.png" cropped_img.save(save_name) # 调用函数实例化参数 image_file = 'example.jpg' destination_dir = './sliced_images/' slice_image(image_file, destination_dir)[^1] ``` 这段代码定义了一个名为`slice_image()` 的函数,它接收输入像路径、输出文件夹位置以及其他可选参数如行数列数,默认情况下会把原始像分成四个相等的部分。 #### 方法二:OpenCV库的应用 对于更复杂的场景或者当涉及到计算机视觉任务时,OpenCV可能是更好的选择。此开源框架提供了丰富的功能集,可用于读写不同类型的媒体数据,并执行诸如变换、滤波等各种运算。这里给出一段基于OpenCV的例子: ```python import cv2 import os def split_image_cv(image_path, outdir, grid_size=(2, 2)): image = cv2.imread(image_path) h, w = image.shape[:2] dh, dw = h // grid_size[0], w // grid_size[1] patches = [] for i in range(grid_size[0]): for j in range(grid_size[1]): patch = image[i*dh:(i+1)*dh,j*dw:(j+1)*dw,:] filename = os.path.join(outdir,f'patch{i}{j}.jpg') cv2.imwrite(filename, patch) patches.append(patch) split_image_cv('input_image.png', './patches/',(3,4))[^2] ``` 上述脚本同样实现了按指定行列数目划分一幅给定像的功能;不过这次采用了OpenCV特有的语法结构与特性。 #### 方法三:批量处理及高级选项 如果需要更加精细控制每一片的具体尺寸或是希望一次性处理多张照片,则可以考虑借鉴一些专门针对此类需求设计的工作流程或工具包。例如,在某些项目中可能还会遇到这样的情况——不仅要把单幅画作拆解开来,还要能将其重新组装回去而不改变原有的分辨率其他属性[^3]。 在这种情形下,除了前面提到的基础逻辑外,还需要额外编写辅助性的子程序去管理整个过程中的细节问题,比如确保所有片段都具有相同的宽高比例、调整边界条件下的填充策略等等。 综上所述,无论是初学者还是有一定经验的人都可以根据自己的实际应用场景挑选合适的技术方案来完成这项工作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xavier Jiezou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值