menu 贺大礼(乱丶心)的博客
python批量压缩图片,带透明背景的图会保留透明背景
433 浏览 | 2024-06-14 | 阅读时间: 约 1 分钟 | 分类: 服务器相关,python | 标签:
请注意,本文编写于 159 天前,最后修改于 159 天前,其中某些信息可能已经过时。
from PIL import Image
import os
import shutil
import errno
import subprocess


def compress_image(image_path, output_dir, quality=90):
    """压缩图片并保存到output_path"""
    # 获取原始图片的文件名和扩展名
    basename = os.path.basename(image_path)

    # 获取图片的扩展名(格式)
    img_format = basename.split('.')[-1]

    # 如果图片格式为'jpg',需要转换为'JPEG'才能正确保存
    if img_format.lower() == 'jpg':
        img_format = 'JPEG'
    else:
        img_format = img_format.upper()

    # 构造输出路径
    output_path = output_dir

    picture = Image.open(image_path)

    # 如果图像包含透明度通道,将其转换为RGB模式
    if picture.mode in ('RGBA', 'LA') or (picture.mode == 'P' and 'transparency' in picture.info):
        print(image_path)
        # 常常使用子进程调用 pngquant 命令行工具进行图片压缩  https://pngquant.org/  加入path环境变量
        command = f'pngquant --quality={quality} -o {output_path} --force {image_path}'
        subprocess.call(command, shell=True)
        return

    # If the image has mode 'P', convert it to 'RGB'
    if picture.mode != 'RGB':
        # 将图像转换为RGB模式,丢弃透明度信息
        picture = picture.convert('RGB')

    # 保存为JPEG格式
    picture.save(output_path, img_format, optimize=True, quality=quality)


def copy_with_structure(input_directory, output_directory):
    # 检查输入路径是否存在
    if not os.path.exists(input_directory):
        raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), input_directory)

    # 遍历输入目录中所有的文件和目录,包括子目录
    for root, dirs, files in os.walk(input_directory):
        # 对于每个子目录,创建相应的子目录在输出目录中
        for dir in dirs:
            input_dir_path = os.path.join(root, dir)
            output_dir_path = input_dir_path.replace(input_directory, output_directory, 1)

            try:
                # 如果输出目录不存在,创建它
                os.makedirs(output_dir_path, exist_ok=True)
            except PermissionError:
                print(f"Permission denied while creating directory: {output_dir_path}")

        for file in files:
            input_file_path = os.path.join(root, file)
            output_file_path = input_file_path.replace(input_directory, output_directory, 1)

            try:
                if not os.path.exists(output_file_path):
                    if input_file_path.lower().endswith(('.png', '.jpg', '.jpeg')):
                        # 检查文件大小,如果大于10KB(10240字节),则压缩
                        if os.path.getsize(input_file_path) > 10240:
                            compress_image(input_file_path, output_file_path, 60)
                        else:
                            # 如果文件大小小于10KB,直接复制
                            shutil.copy2(input_file_path, output_file_path)
                    else:
                        # 对于非图片文件,简单地将它们复制到新的位置
                        shutil.copy2(input_file_path, output_file_path)
            except (PermissionError, OSError) as e:
                print(f"Error occurred while copying file: {input_file_path}. Error: {str(e)}")


if __name__ == '__main__':
    copy_with_structure("D:\\old_imgs", "D:\\new_imgs")
知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!