Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions contributors/rs1973/process_img1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
""""
Creator:rs1973
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,
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)
if not filenames:
return

if kind == '.gif':
print('注意:请确保图像列表中所有图片的大小都一样')
gif(filenames, outpath, duration, name)
else:
with ThreadPoolExecutor(process) as pool:
futures = [pool.submit(process_img, outpath,
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)
46 changes: 46 additions & 0 deletions contributors/rs1973/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 批量图片尺寸与通道处理工具

**Creator:** rs1973
**E-mail:** dingzheng_2023@qq.com / gunshi98@gmail.com

本工具支持对 **单张图片** 或 **整个目录的全部图片** 进行批量处理,包括:

- 调整图片尺寸
- 统一色彩通道(可选择去除或保留透明通道 alpha)
- 批量导出到指定目录
- 支持 `.jpg / .jpeg / .png / .bmp / .tiff / .webp` 格式
- 支持 GIF 合成(单线程)

程序内部使用 **多线程** 加速大量图片处理,默认为5线程。

---

## 功能特点

| 功能 | 说明 |
|-----|----------------------------------------------------------------|
| 批量筛选图片 | 自动忽略非图片文件 |
| 多线程处理 | 提升处理速度,默认为5线程 |
| 支持保留 / 去除透明通道 | 当输出格式支持alpha,可以选择保留或丢弃,丢弃时会将原本的alpha像素替换成白色(后续会添加颜色选择选项) |
| 自适应缩放或填充模式 | 保证目标尺寸一致:当目标大小小于原图时,会缩放/拉伸原图,大于且长宽比例与目标大小相同时,则直接缩放,反之则会用白色填充图片 |
| GIF 合成 | 可根据延迟参数调节帧率,默认300ms/帧 |

---

## 基本使用示例

```python
from contributors.rs1973.process_img1.py 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' 时使用
)
Empty file added tests/test_code/test_img.py
Empty file.