Error in user YAML: (<unknown>): found a tab character that violate indentation while scanning a plain scalar at line 3 column 3
---
- oeasy Python 0655
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
- 本教程同步发布在:
- 个人网站: `https://oeasy.org`
- 蓝桥云课: `https://www.lanqiao.cn/courses/3584`
- GitHub: `https://github.com/overmind1980/oeasy-python-tutorial`
- Gitee: `https://gitee.com/overmind1980/oeasypython`
---import argparse
from PIL import Image
import os
class PixelArtConverter:
def __init__(self, input_path, output_path, crop_region=None, color_count=16, block_size=8):
"""
初始化像素艺术转换器
:param input_path: 输入图片路径
:param output_path: 输出图片路径
:param crop_region: 裁剪区域,格式为(x1, y1, x2, y2),None表示不裁剪
:param color_count: 色彩数量,范围2-256
:param block_size: 像素块大小
"""
self.input_path = input_path
self.output_path = output_path
self.crop_region = crop_region
self.color_count = max(2, min(color_count, 256)) # 限制在2-256之间
self.block_size = max(1, block_size) # 确保至少为1
self.image = None
def load_image(self):
"""加载并预处理图片"""
if not os.path.exists(self.input_path):
raise FileNotFoundError(f"输入文件不存在: {self.input_path}")
# 打开图片并转换为RGB模式(处理透明通道)
self.image = Image.open(self.input_path)
if self.image.mode in ('RGBA', 'LA'):
background = Image.new(self.image.mode[:-1], self.image.size, (255, 255, 255))
background.paste(self.image, self.image.split()[-1])
self.image = background
self.image = self.image.convert('RGB')
def crop_image(self):
"""裁剪图片"""
if self.crop_region and self.image:
x1, y1, x2, y2 = self.crop_region
# 确保裁剪区域有效
width, height = self.image.size
x1 = max(0, min(x1, width))
y1 = max(0, min(y1, height))
x2 = max(x1 + 1, min(x2, width))
y2 = max(y1 + 1, min(y2, height))
self.image = self.image.crop((x1, y1, x2, y2))
def convert_to_pixel_art(self):
"""将图片转换为像素风格"""
if not self.image:
raise ValueError("未加载图片,请先调用load_image()")
width, height = self.image.size
# 计算缩小后的尺寸
small_width = width // self.block_size
small_height = height // self.block_size
# 缩小图片(创建像素块效果)
img_small = self.image.resize((small_width, small_height), Image.NEAREST)
# 放大回原始尺寸
img_pixel = img_small.resize((width, height), Image.NEAREST)
# 减少色彩数量
img_quantized = img_pixel.quantize(colors=self.color_count)
# 转换回RGB模式以保存为JPG
self.image = img_quantized.convert('RGB')
def save_image(self):
"""保存处理后的图片"""
if self.image:
# 创建输出目录(如果需要)
output_dir = os.path.dirname(self.output_path)
if output_dir and not os.path.exists(output_dir):
os.makedirs(output_dir)
self.image.save(self.output_path, 'JPEG', quality=95)
print(f"图片已保存至: {self.output_path}")
def process(self):
"""执行完整处理流程"""
try:
self.load_image()
print(f"加载图片成功: {self.input_path}")
print(f"原始尺寸: {self.image.size[0]}x{self.image.size[1]}")
self.crop_image()
if self.crop_region:
print(f"裁剪后尺寸: {self.image.size[0]}x{self.image.size[1]}")
self.convert_to_pixel_art()
print(f"像素风格转换完成: {self.color_count}种颜色, {self.block_size}x{self.block_size}像素块")
self.save_image()
return True
except Exception as e:
print(f"处理失败: {str(e)}")
return False
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='JPG图片裁剪与像素风格转换工具')
parser.add_argument('--input', required=True, help='输入JPG图片路径')
parser.add_argument('--output', required=True, help='输出JPG图片路径')
parser.add_argument('--crop', nargs=4, type=int, help='裁剪区域坐标 (x1 y1 x2 y2),如 --crop 100 100 500 500')
parser.add_argument('--colors', type=int, default=16, help='色彩数量 (2-256),默认16')
parser.add_argument('--block-size', type=int, default=8, help='像素块大小 (正整数),默认8')
args = parser.parse_args()
# 创建转换器实例并处理图片
converter = PixelArtConverter(
input_path=args.input,
output_path=args.output,
crop_region=args.crop,
color_count=args.colors,
block_size=args.block_size
)
converter.process()
- 本文来自 oeasy Python 系统教程。
- 想完整、扎实学 Python,
- 搜索 oeasy 即可。