mlyde 发表于 2022-1-18 16:32

python 缩放并裁剪图片 制作图片缩略图

# 缩放裁剪图片
好久没发东西了,不知道什么样算活跃,水一篇吧{:301_997:} 。
## 说明
现在有一文件夹中存在许多分辨率不同的图片或文件夹,需要裁剪至指定大小以便作为网页中的图片缩略图。

cut 函数,将图片裁剪为指定大小,统一分辨率,缩放后取图片中间部分,超出的部分直接裁剪掉。
还有一个函数 cut2,为等比缩放至x或y为定值。

## 用法
缩放裁剪后的x、y像素值在代码开始部分更改即可。
默认只使用 cut 函数,使用 cut2 函数时需在代码第18-20行更改。
**注意:**
>1.缩放裁剪后会`覆盖`原文件,需要的话,请在缩放裁剪前备份图片。
>2.没有做文件夹验证,请确认输入正确的文件夹路径,并确保文件夹中只有图片。
>3.多次缩放可能会使图片变得模糊,尤其是文字边缘。

## 完整代码

import cv2
import os
import numpy as np

# cut 裁剪后的 xy
target_x = 286
target_y = 203

def get_dir(dir):
        """ 遍历文件夹下所有的文件名 """

        list1 = os.listdir(dir)
        for l in list1:
                l = f'{dir}/{l}'
                if(os.path.isdir(l)):
                        get_dir(l)
                else:
                        cut(l)
                        # cut2(l,x=800)
                        # cut2(l,y=400)

def cut(inputdir = './t.jpg'):
        """ 图片裁剪 """

        # 裁剪后的文件名为
        # outputdir = inputdir[:-4] + '_over.jpg'
        # 设置为相同文件名,覆盖原文件
        outputdir = inputdir

        # img = cv2.imread(inputdir)        # imread读取不能包含中文文件名
        img = cv2.imdecode(np.fromfile(inputdir, dtype=np.uint8), cv2.IMREAD_UNCHANGED)

    # imdecode读取图像默BGR通道排列,
    # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)        # 转换为RGB

        # img.shape:
        in_y, in_x = img.shape[:2]
        print(img.shape)

        scale = target_x / target_y
        scale1 = in_x / in_y

        if(scale1 >= scale):
                size = (int(in_x/(in_y/target_y)), target_y)
                # print(1, size)
        elif(scale1 < scale):
                size = (target_x, int(in_y/(in_x/target_x)))
                # print(2, size)
        else:
                size = (target_x, target_y)
                print('error')

        # 缩放到size=(x,y)
        resized = cv2.resize(img, size, interpolation=cv2.INTER_AREA)

        # 展示裁剪后的图片
        # cv2.imshow('image', resized)
        # cv2.waitKey(0)
        # print('x', resized.shape, 'y', resized.shape)

        if(resized.shape == target_x):
                # x=target_x
                y0 = resized.shape // 2 - target_y//2
                y1 = y0 + target_y
                x0 = 0
                x1 = target_x
        if(resized.shape == target_y):
                # y=target_y
                y0 = 0
                y1 = target_y
                x0 = resized.shape // 2 - target_x//2
                x1 = x0 + target_x

        output_img = resized

        # cv2.imwrite(outputdir, output_img)        # imwrite保存文件名不能包含中文
        cv2.imencode('.jpg', output_img).tofile(outputdir)

def cut2(inputdir = './t.jpg', x=0, y=0):
        """ 等比缩放,不裁剪 """
        # outputdir = inputdir[:-4] + '_over.jpg'
        outputdir = inputdir
        img = cv2.imdecode(np.fromfile(inputdir, dtype=np.uint8), cv2.IMREAD_UNCHANGED)

        in_y, in_x = img.shape[:2]
        if(x):
                # 等比缩小为x=
                fxy = x/in_x
        elif(y):
                # 等比缩小为y=
                fxy = y/in_y
        else:
                fxy = 1

        # 按比例缩放,fx:x轴缩放比例,fy:y轴缩放比例
        output_img = cv2.resize(img, (0,0), fx=fxy, fy=fxy, interpolation=cv2.INTER_AREA)
        cv2.imencode('.jpg', output_img).tofile(outputdir)

if __name__ == "__main__":
        original_dir = input('文件夹路径:')
        get_dir(original_dir)

页: [1]
查看完整版本: python 缩放并裁剪图片 制作图片缩略图