From 1010c0a16579465514009523cbb2f7aeaad487e6 Mon Sep 17 00:00:00 2001 From: rs1973-bit Date: Wed, 5 Nov 2025 18:15:15 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=9B=BE=E7=89=87=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contributors/rs1973-bit/process_img1.py | 135 ++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 contributors/rs1973-bit/process_img1.py diff --git a/contributors/rs1973-bit/process_img1.py b/contributors/rs1973-bit/process_img1.py new file mode 100644 index 0000000..381359f --- /dev/null +++ b/contributors/rs1973-bit/process_img1.py @@ -0,0 +1,135 @@ +"""" +Creator:rs1973-bit +E-mail:dingzheng_2023@qq.com/gunshi98@gmail.com +Description:支持输入一个目录或一张图片,修改它(或者整个目录里)的图片尺寸,色彩通道,并决定是否留下图像的 +alpha值,会自动筛选不是图片或不支持的格式 程序为多线程(多进程下使用笔记本测试时cpu过热),但gif合成 +暂时不支持多线程 + +ps:这是我的第一个项目,有很多做得不够好的地方,请多包容 +""" + +import os +import time +from concurrent.futures import ThreadPoolExecutor + + +from PIL import Image, ImageOps + + +def get_img(srcpath=None, sinfile=None): + """筛选目录中的非图片文件,只筛选一层,不读取子目录里的文件""" + + img_lst = [] + not_img = '' + if srcpath: + for dirpath, dirname, filenames in os.walk(srcpath): + if filenames: + for img in filenames: + img = os.path.join(dirpath, img) + if os.path.isfile(img): + if os.path.splitext(img)[1].lower() in {".jpg", ".jpeg", ".png", ".bmp", ".tiff", '.webp'}: + img_lst.append(img) + else: + not_img += f'{img}\n' + else: + print(f'注意: 目录 {dirpath} 中没有图片') + return [] + + if not_img: + print(f'提示: 以下文件/目录不是图片:\n{not_img}') + return img_lst + + if sinfile: + if os.path.splitext(sinfile)[1].lower() in {".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff", '.webp'}: + return [sinfile] + else: + print(f'错误: 文件 {sinfile} 不是图片') + return [] + + +def normal_img(im, input_info: tuple, outpath: str, kind: str, img: str, alpha: bool): + """图像的缩放处理,每一个格式都会用到""" + if input_info: + x, y = input_info + if round(int(x) / im.size[0], 2) == round(int(y) / im.size[1], 2): + real_tuple = (int(x), int(y)) + im = im.resize(real_tuple) + else: + if not alpha: + pad_im = ImageOps.pad(im, (int(x), int(y)), color='#FFFFFF') + else: + pad_im = ImageOps.pad(im, (int(x), int(y)), + color=(0, 0, 0, 0), centering=(0.5, 0.5)) + + im = pad_im + + base_name = os.path.basename(img) + name_only = os.path.splitext(base_name)[0] + save_path = os.path.join(outpath, name_only + kind) + im.save(save_path, format=kind[1:].upper()) + im.close() + + +def gif(filenames=None, outpath=None, duration=300, name='index'): + """合成gif""" + try: + img_lst = [Image.open(i).copy().convert('RGB') for i in filenames] + img_lst[0].save( + os.path.join(outpath, f'{name}.gif'), + append_images=img_lst[1:], + duration=duration, + loop=0, + optimize=True + ) + except ValueError as e: + print(f'错误: 序列中图片大小不一致, {e}') + + +def process_img(outpath=None, input_info=None, kind=None, alpha=None, img=None): + """修改图片中的alpha""" + if kind in ('.png', '.webp', '.bmp'): + with Image.open(img) as im: + im = im.convert('RGBA') + if not alpha: + new_im = im.copy() + new_im.convert('RGB') + alpha_pixel = im.getdata() + write_pixel = [] + for item in alpha_pixel: + r, g, b, a = item + if a == 0: + write_pixel.append((255, 255, 255)) + else: + write_pixel.append((r, g, b)) + new_im.putdata(write_pixel) + im = new_im + normal_img(im, input_info, outpath, kind, img, alpha) + else: + with Image.open(img) as im: + if im.mode == 'RGBA': + im = im.convert('RGB') + normal_img(im, input_info, outpath, kind, img, alpha) + + +def main(srcpath: str = None, outpath: str = None, sinfile: str = None, + input_info: tuple = None, kind: str = '.jpeg', alpha: bool = False, + duration: int = 300, process: int = 5): + """主逻辑函数""" + start = time.time() + + filenames = get_img(srcpath, sinfile) + if not filenames: + return + + if kind == '.gif': + print('注意:请确保图像列表中所有图片的大小都一样') + gif(filenames, outpath, duration) + else: + with ThreadPoolExecutor(process) as pool: + futures = [pool.submit(process_img, outpath, + input_info, kind, alpha, img) for img in filenames] + for fut in futures: + fut.result() + + end = time.time() + print(f'处理完成, 耗时: {end - start:.2f}s') From fcc74f8eecc3c908e3bf58480d2740fc3b1b33a0 Mon Sep 17 00:00:00 2001 From: rs1973-bit Date: Wed, 5 Nov 2025 21:08:05 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=9B=BE=E7=89=87=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{rs1973-bit => rs1973}/process_img1.py | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) rename contributors/{rs1973-bit => rs1973}/process_img1.py (88%) diff --git a/contributors/rs1973-bit/process_img1.py b/contributors/rs1973/process_img1.py similarity index 88% rename from contributors/rs1973-bit/process_img1.py rename to contributors/rs1973/process_img1.py index 381359f..bfd7d97 100644 --- a/contributors/rs1973-bit/process_img1.py +++ b/contributors/rs1973/process_img1.py @@ -1,5 +1,5 @@ """" -Creator:rs1973-bit +Creator:rs1973 E-mail:dingzheng_2023@qq.com/gunshi98@gmail.com Description:支持输入一个目录或一张图片,修改它(或者整个目录里)的图片尺寸,色彩通道,并决定是否留下图像的 alpha值,会自动筛选不是图片或不支持的格式 程序为多线程(多进程下使用笔记本测试时cpu过热),但gif合成 @@ -11,11 +11,8 @@ import os import time from concurrent.futures import ThreadPoolExecutor - - from PIL import Image, ImageOps - def get_img(srcpath=None, sinfile=None): """筛选目录中的非图片文件,只筛选一层,不读取子目录里的文件""" @@ -112,9 +109,10 @@ def process_img(outpath=None, input_info=None, kind=None, alpha=None, img=None): def main(srcpath: str = None, outpath: str = None, sinfile: str = None, - input_info: tuple = None, kind: str = '.jpeg', alpha: bool = False, - duration: int = 300, process: int = 5): + img_size: tuple = None, kind: str = '.jpeg', alpha: bool = False, + duration: int = 300, process: int = int(os.cpu_count()//2), name='index'): """主逻辑函数""" + print('开始处理图片……') start = time.time() filenames = get_img(srcpath, sinfile) @@ -123,13 +121,19 @@ def main(srcpath: str = None, outpath: str = None, sinfile: str = None, if kind == '.gif': print('注意:请确保图像列表中所有图片的大小都一样') - gif(filenames, outpath, duration) + gif(filenames, outpath, duration, name) else: with ThreadPoolExecutor(process) as pool: futures = [pool.submit(process_img, outpath, - input_info, kind, alpha, img) for img in filenames] + img_size, kind, alpha, img) for img in filenames] for fut in futures: fut.result() end = time.time() print(f'处理完成, 耗时: {end - start:.2f}s') + +# src = r"C:\Users\rollingstone\OneDrive\Desktop\001" +# out = r"C:\Users\rollingstone\OneDrive\Desktop\s\re" + +# if __name__ == '__main__': +# main(srcpath=src, outpath=out, alpha=False, kind='.gif', name='hello', duration=250) From 962b8b40ec4cfb2a30717a39a0f73b25090a5a60 Mon Sep 17 00:00:00 2001 From: rs1973-bit Date: Wed, 5 Nov 2025 21:11:32 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=85=B3=E4=BA=8E?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=A4=84=E7=90=86=E5=9B=BE=E7=89=87=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81,=E5=B7=B2=E7=BB=8Freadme=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contributors/rs1973/readme.md | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 contributors/rs1973/readme.md diff --git a/contributors/rs1973/readme.md b/contributors/rs1973/readme.md new file mode 100644 index 0000000..7491d9b --- /dev/null +++ b/contributors/rs1973/readme.md @@ -0,0 +1,46 @@ +# 批量图片尺寸与通道处理工具 + +**Creator:** rs1973 +**E-mail:** dingzheng_2023@qq.com / gunshi98@gmail.com + +本工具支持对 **单张图片** 或 **整个目录的全部图片** 进行批量处理,包括: + +- 调整图片尺寸 +- 统一色彩通道(可选择去除或保留透明通道 alpha) +- 批量导出到指定目录 +- 支持 `.jpg / .jpeg / .png / .bmp / .tiff / .webp` 格式 +- 支持 GIF 合成(单线程) + +程序内部使用 **多线程** 加速大量图片处理(默认线程数 = CPU核心数 / 2)。 + +--- + +## ✨ 功能特点 + +| 功能 | 说明 | +|-----|------| +| 批量筛选图片 | 自动忽略非图片文件 | +| 多线程处理 | 提升处理速度,避免界面卡死 | +| 支持保留 / 去除透明通道 | 去除透明区域时自动填充白色背景 | +| 自适应缩放或填充模式 | 保证目标尺寸一致 | +| GIF 合成 | 可根据延迟参数调节帧率 | + +--- + +## 🔧 基本使用示例 + +```python +from your_module_name import main + +src = r"C:\path\to\input_dir" +out = r"C:\path\to\output_dir" +size = (1000, 1000) + +main( + srcpath=src, + outpath=out, + img_size=size, + alpha=False, # 是否保留透明通道 + kind='.png', # 输出格式 + duration=300 # GIF 合成时的帧间隔,仅在 kind='.gif' 时使用 +) \ No newline at end of file From 28ca0c7ff7cb6fac0c411f96719cea8d50277dbf Mon Sep 17 00:00:00 2001 From: rs1973-bit Date: Wed, 5 Nov 2025 21:12:44 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=85=B3=E4=BA=8E?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=A4=84=E7=90=86=E5=9B=BE=E7=89=87=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81,=E5=B7=B2=E7=BB=8Freadme=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contributors/rs1973/readme.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contributors/rs1973/readme.md b/contributors/rs1973/readme.md index 7491d9b..8325f66 100644 --- a/contributors/rs1973/readme.md +++ b/contributors/rs1973/readme.md @@ -17,13 +17,13 @@ ## ✨ 功能特点 -| 功能 | 说明 | -|-----|------| -| 批量筛选图片 | 自动忽略非图片文件 | -| 多线程处理 | 提升处理速度,避免界面卡死 | +| 功能 | 说明 | +|-----|-----------------| +| 批量筛选图片 | 自动忽略非图片文件 | +| 多线程处理 | 提升处理速度,默认为5线程 | | 支持保留 / 去除透明通道 | 去除透明区域时自动填充白色背景 | -| 自适应缩放或填充模式 | 保证目标尺寸一致 | -| GIF 合成 | 可根据延迟参数调节帧率 | +| 自适应缩放或填充模式 | 保证目标尺寸一致 | +| GIF 合成 | 可根据延迟参数调节帧率 | --- From 4083fd405a1d83640249f09eb63e6f5c6f5e22dd Mon Sep 17 00:00:00 2001 From: rs1973-bit Date: Wed, 5 Nov 2025 21:18:26 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=85=B3=E4=BA=8E?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=A4=84=E7=90=86=E5=9B=BE=E7=89=87=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81,=E5=B7=B2=E7=BB=8Freadme=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contributors/rs1973/readme.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/contributors/rs1973/readme.md b/contributors/rs1973/readme.md index 8325f66..a8205ef 100644 --- a/contributors/rs1973/readme.md +++ b/contributors/rs1973/readme.md @@ -11,23 +11,23 @@ - 支持 `.jpg / .jpeg / .png / .bmp / .tiff / .webp` 格式 - 支持 GIF 合成(单线程) -程序内部使用 **多线程** 加速大量图片处理(默认线程数 = CPU核心数 / 2)。 +程序内部使用 **多线程** 加速大量图片处理,默认为5线程。 --- -## ✨ 功能特点 +## 功能特点 -| 功能 | 说明 | -|-----|-----------------| -| 批量筛选图片 | 自动忽略非图片文件 | -| 多线程处理 | 提升处理速度,默认为5线程 | -| 支持保留 / 去除透明通道 | 去除透明区域时自动填充白色背景 | -| 自适应缩放或填充模式 | 保证目标尺寸一致 | -| GIF 合成 | 可根据延迟参数调节帧率 | +| 功能 | 说明 | +|-----|----------------------------------------------------------------| +| 批量筛选图片 | 自动忽略非图片文件 | +| 多线程处理 | 提升处理速度,默认为5线程 | +| 支持保留 / 去除透明通道 | 当输出格式支持alpha,可以选择保留或丢弃,丢弃时会将原本的alpha像素替换成白色(后续会添加颜色选择选项) | +| 自适应缩放或填充模式 | 保证目标尺寸一致:当目标大小小于原图时,会缩放/拉伸原图,大于且长宽比例与目标大小相同时,则直接缩放,反之则会用白色填充图片 | +| GIF 合成 | 可根据延迟参数调节帧率,默认300ms/帧 | --- -## 🔧 基本使用示例 +## 基本使用示例 ```python from your_module_name import main From c0f09dbaa96208ac5dcdabaf917359e9c325412e Mon Sep 17 00:00:00 2001 From: rs1973-bit Date: Wed, 5 Nov 2025 21:18:45 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=85=B3=E4=BA=8E?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=A4=84=E7=90=86=E5=9B=BE=E7=89=87=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81,=E4=BB=A5=E5=8F=8Areadme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_code/test_img.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/test_code/test_img.py diff --git a/tests/test_code/test_img.py b/tests/test_code/test_img.py new file mode 100644 index 0000000..e69de29 From 5650372a9685dd4c4f719fd98cc6253ca6f3eb85 Mon Sep 17 00:00:00 2001 From: rs1973-bit Date: Wed, 5 Nov 2025 21:20:28 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=85=B3=E4=BA=8E?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=A4=84=E7=90=86=E5=9B=BE=E7=89=87=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81,=E4=BB=A5=E5=8F=8Areadme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contributors/rs1973/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributors/rs1973/readme.md b/contributors/rs1973/readme.md index a8205ef..3521029 100644 --- a/contributors/rs1973/readme.md +++ b/contributors/rs1973/readme.md @@ -30,7 +30,7 @@ ## 基本使用示例 ```python -from your_module_name import main +from contributors.rs1973.process_img1.py import main src = r"C:\path\to\input_dir" out = r"C:\path\to\output_dir"