批量对图片进行切割 压缩(附python源码)

一、解决的问题

1.图片指定位置和大小切割

2.指定大小切割

3.指定按照原大小比例切割

4.压缩图片为指定大小

二、具体原理、代码及执行结果

1.图片指定位置和大小切割

需要指定剪切的部分在原图片的位置,本代码是设置box1 = (0, 50, 100, 100)来设置左,上,右,下四个参数来实现剪切。

话不多说直接上代码

# coding: utf-8
from PIL import Image
import os
import os.path
import numpy as np
import cv2
#指明被遍历的文件夹
rootdir = r"D:/soft/Notebook_workspace/myself/photo_add/01/"
for parent, dirnames, filenames in os.walk(rootdir):#遍历每一张图片
    for filename in filenames:
        print('parent is :' + parent)
        print('filename is :' + filename)
        currentPath = os.path.join(parent, filename)
        print('the fulll name of the file is :' + currentPath)
   
        img = Image.open(currentPath)
        print (img.format, img.size, img.mode)
        box1 = (0, 50, 100, 100)#设置左、上、右、下的像素
        image1 = img.crop(box1) # 图像裁剪
        image1.save(r"D:/soft/Notebook_workspace/myself/photo_add/05/"+'\\'+filename) #存储裁剪得到的图像

执行结果:

2.指定大小切割

在指定大小切割时,我们会有一个问题,那就是原图片大小与需要切割的大小不成整数比时,无法完美切割,本文以图片完整性优先,在不成整数比时采用从边界开始反向剪裁来保证图片数据的完整性,当然,你可以自己更改代码将其舍弃。

(1)正方形

将原图片切割成边长为w的正方形,通过设置参数w设置需要切成图片块的大小,默认大小为w*w

代码部分如下:

import os
from PIL import Image

#用PIL库批量裁剪指定大小的图像(自动填充)
def img_crop(img_path, save_path):
    files = os.listdir(img_path)
    for file in files:
        a, b = os.path.splitext(file)
        img = Image.open(os.path.join(img_path + "/" + file))
        width, hight = img.size
        w = 100  # 需要切成图片块的大小,默认大小为w*w,可以自己设置
        id = 1
        i = 0
        padw = padh = 0  # 当宽高除不尽切块大小时,对最后一块进行填充
        if width % w != 0:
            padw = 1  # 宽除不尽的情况
        if hight % w != 0:
            padh = 1  # 高除不尽的情况

        # 默认从最左上角向右裁剪,再向下裁剪
        while i + w <= hight:
            j = 0
            while j + w <= width:
                new_img = img.crop((j, i, j + w, i + w))
                new_img.save(save_path + a + "_" + str(id) + b)
                id += 1
                j += w
            if padw == 1:  # 宽有除不尽的情况
                new_img = img.crop((width - w, i, width, i + w))
                new_img.save(save_path + a + "_" + str(id) + b)
                id += 1
            i = i + w

        if padh == 1:  # 高除不尽的情况
            j = 0
            while j + w <= width:
                new_img = img.crop((j, hight - w, j + w, hight))
                new_img.save(save_path + a + "_" + str(id) + b)
                id += 1
                j += w
            if padw == 1:
                new_img = img.crop((width - w, hight - w, width, hight))
                new_img.save(save_path + a + "_" + str(id) + b)
                id += 1


if __name__ == '__main__':
    # img_path:输入图像的路径
    img_path = r"D:/soft/Notebook_workspace/myself/photo_add/01/"
    # save_path:图像保存的位置
    save_path = r"D:/soft/Notebook_workspace/myself/photo_add/03/"
    if not os.path.exists(save_path):           # 如果没有这个文件夹,就新建
        os.makedirs(save_path) 
    img_crop(img_path, save_path)

执行结果:

(2)矩形

与切割成为正方形类似,唯一的区别是需要设置横向长度w1和纵向长度w2两个参数。

函数代码部分如下(其他部分与上方相同):

def img_crop(img_path, save_path):
    files = os.listdir(img_path)
    for file in files:
        a, b = os.path.splitext(file)
        img = Image.open(os.path.join(img_path + "/" + file))
        width, hight = img.size
        w1 = 120  # 需要切成图片块的大小,默认大小为w*w,可以自己设置
        w2=80
        id = 1
        i = 0
        padw = padh = 0  # 当宽高除不尽切块大小时,对最后一块进行填充
        if width % w1 != 0:
            padw = 1  # 宽除不尽的情况
        if hight % w2 != 0:
            padh = 1  # 高除不尽的情况

        # 默认从最左上角向右裁剪,再向下裁剪
        while i + w2 <= hight:
            j = 0
            while j + w1 <= width:
                new_img = img.crop((j, i, j + w1, i + w2))
                new_img.save(save_path + a + "_" + str(id) + b)
                id += 1
                j += w1
            if padw == 1:  # 宽有除不尽的情况
                new_img = img.crop((width - w1, i, width, i + w2))
                new_img.save(save_path + a + "_" + str(id) + b)
                id += 1
            i = i + w2

        if padh == 1:  # 高除不尽的情况
            j = 0
            while j + w1 <= width:
                new_img = img.crop((j, hight - w2, j + w1, hight))
                new_img.save(save_path + a + "_" + str(id) + b)
                id += 1
                j += w1
            if padw == 1:
                new_img = img.crop((width - w1, hight - w2, width, hight))
                new_img.save(save_path + a + "_" + str(id) + b)
                id += 1

3.指定按照原大小比例切割

可以将原图片的长高按照比例切割,你只需要设置两个参数就可以 heightCutNum = 2; widthCutNum = 2; 其中heightCutNum是将剪裁后的图片的高变为的1/heightCutNum倍,另一个也是一样的;

代码部分如下:

import cv2
import os

# Cutting the input image to h*w blocks
heightCutNum = 2;
widthCutNum = 2;


# The folder path of input and output
inPath = r"D:/soft/Notebook_workspace/myself/photo_add/01/"
outPath = r"D:/soft/Notebook_workspace/myself/photo_add/04/"


for f in os.listdir(inPath):

    path = inPath + f.strip()
    print(path)
    img = cv2.imread(path)    

    # The size of each input image
    height = img.shape[0]
    width = img.shape[1]
    
    # The size of block that you want to cut
    heightBlock = int(height / heightCutNum)
    widthBlock = int(width / widthCutNum)

    for i in range(0,heightCutNum):
        for j in range(0,widthCutNum):
            cutImage = img[i*heightBlock:(i+1)*heightBlock, j*widthBlock:(j+1)*widthBlock]
            savePath = outPath + f.strip()[0:5] + "_" + str(i) + str(j) + ".jpg"
            cv2.imwrite(savePath,cutImage)
        

执行结果:

4.压缩图片为指定大小

将大小不同的图片压缩成指定大小,只需要对 pic_new = pic_org.resize((w1, w2), Image.ANTIALIAS) 的两个参数进行更改就好,w1为长,w2为高。

代码部分如下:

# 图片压缩 压缩到相同的大小
from PIL import Image
import os
 
file_path = r"D:/soft/Notebook_workspace/myself/photo_add/01/"    # 原始图像路径
save_path = r"D:/soft/Notebook_workspace/myself/photo_add/02/"  # 修改后图像存储的路径
 
if not os.path.exists(save_path):           # 如果没有这个文件夹,就新建
    os.makedirs(save_path)
 
for root, dirs, files in os.walk(file_path):
    for file in files:                      # 展现各文件
        picture_path = os.path.join(root, file)    # 得到图像的绝对路径
        pic_org = Image.open(picture_path)               # 打开图像
        pic_new = pic_org.resize((100, 50), Image.ANTIALIAS)   # 图像尺寸修改
        pic_new_path = os.path.join(save_path, file)  # 新图像存储绝对路径
        pic_new.save(pic_new_path)  # 存储文件
        print("%s 已裁切完成!" %pic_new_path)

执行结果:

相关推荐

  1. 使用Python批量压缩图片

    2023-12-09 10:54:03       27 阅读
  2. 用户上传图片进行压缩

    2023-12-09 10:54:03       37 阅读
  3. 使用Python多线程批量压缩图片文件

    2023-12-09 10:54:03       30 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-09 10:54:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-09 10:54:03       101 阅读
  3. 在Django里面运行非项目文件

    2023-12-09 10:54:03       82 阅读
  4. Python语言-面向对象

    2023-12-09 10:54:03       91 阅读

热门阅读

  1. 第二十一 网络通信

    2023-12-09 10:54:03       48 阅读
  2. Kubernetes - 为什么 K8S 在容器里不能调用自己?

    2023-12-09 10:54:03       57 阅读
  3. LinuxBasicsForHackers笔记 -- 日志系统

    2023-12-09 10:54:03       53 阅读
  4. CFD仿真流程

    2023-12-09 10:54:03       53 阅读
  5. 基于IText7 PDF模板填充?

    2023-12-09 10:54:03       58 阅读
  6. chatgpt、百度、讯飞、阿里写一小段SQL对比

    2023-12-09 10:54:03       60 阅读
  7. 利用C++面向对象范式编程求矩形面积 ← 类

    2023-12-09 10:54:03       57 阅读
  8. EAS BOS:Unsupported major.minor version 51.0

    2023-12-09 10:54:03       57 阅读
  9. printf二进制输出

    2023-12-09 10:54:03       52 阅读
  10. Docker 安装 Centos和宝塔

    2023-12-09 10:54:03       57 阅读
  11. Linux中用bash写脚本

    2023-12-09 10:54:03       39 阅读