【办公自动化】如何使用Python库高效自动化处理图像?

在日常办公中,我们经常需要处理大量图像,如产品照片、营销素材、文档扫描件等。手动处理这些图像不仅耗时,还容易出错。通过Python自动化图像处理,我们可以高效地完成批量缩放、裁剪、加水印、格式转换等任务,大大提高工作效率。

本文将介绍两个强大的Python图像处理库:Pillow(PIL的fork版本)和OpenCV,并通过实例展示如何使用它们实现各种图像处理自动化任务。

使用Pillow操作图像

Pillow是Python中最流行的图像处理库之一,它简单易用,功能强大,适合大多数日常图像处理任务。

安装Pillow

pip install Pillow

基本操作

打开和保存图像
from PIL import Image# 打开图像
img = Image.open('example.jpg')# 显示图像信息
print(f"图像格式: {img.format}")
print(f"图像大小: {img.size}")
print(f"图像模式: {img.mode}")# 保存图像(可以指定不同格式)
img.save('example_copy.jpg')  # 保存为JPG
img.save('example.png')       # 保存为PNG
img.save('example.webp', quality=80)  # 保存为WebP,指定质量

图像缩放

PIL.Image.Image 类包含重新调整图像大小的 resize() 方法,参数为指定新尺寸的元组。

from PIL import Imagedef resize_image(input_path, output_path, new_size):"""调整图像大小Args:input_path: 输入图像路径output_path: 输出图像路径new_size: 新尺寸,格式为(宽, 高)"""try:# 打开原始图像img = Image.open(input_path)# 调整大小resized_img = img.resize(new_size)# 保存调整后的图像resized_img.save(output_path)print(f"已将图像从 {img.size} 调整为 {new_size}")return Trueexcept Exception as e:print(f"调整图像大小时出错: {e}")return False# 使用示例
resize_image('example.jpg', 'example_resized.jpg', (800, 600))

等比例缩放

from PIL import Imagedef resize_image_proportionally(input_path, output_path, max_size):"""等比例调整图像大小,保持宽高比Args:input_path: 输入图像路径output_path: 输出图像路径max_size: 最大尺寸,格式为(最大宽度, 最大高度)"""try:# 打开原始图像img = Image.open(input_path)# 获取原始尺寸width, height = img.size# 计算缩放比例max_width, max_height = max_sizescale = min(max_width / width, max_height / height)# 计算新尺寸new_width = int(width * scale)new_height = int(height * scale)# 调整大小resized_img = img.resize((new_width, new_height))# 保存调整后的图像resized_img.save(output_path)print(f"已将图像从 {img.size} 等比例调整为 {resized_img.size}")return Trueexcept Exception as e:print(f"调整图像大小时出错: {e}")return False# 使用示例
resize_image_proportionally('example.jpg', 'example_resized_prop.jpg', (800, 600))

图像裁剪

from PIL import Imagedef crop_image(input_path, output_path, crop_box):"""裁剪图像Args:input_path: 输入图像路径output_path: 输出图像路径crop_box: 裁剪区域,格式为(左, 上, 右, 下)"""try:# 打开原始图像img = Image.open(input_path)# 裁剪图像cropped_img = img.crop(crop_box)# 保存裁剪后的图像cropped_img.save(output_path)print(f"已裁剪图像,裁剪区域: {crop_box}")return Trueexcept Exception as e:print(f"裁剪图像时出错: {e}")return False# 使用示例
crop_image('example.jpg', 'example_cropped.jpg', (100, 100, 500, 400))

图像旋转

PIL.Image.Image 类包含旋转图像的 rotate() 方法,参数为逆时针旋转的角度。

from PIL import Imagedef rotate_image(input_path, output_path, angle, expand=True):"""旋转图像Args:input_path: 输入图像路径output_path: 输出图像路径angle: 旋转角度(逆时针)expand: 是否扩展画布以适应旋转后的图像"""try:# 打开原始图像img = Image.open(input_path)# 旋转图像rotated_img = img.rotate(angle, expand=expand)# 保存旋转后的图像rotated_img.save(output_path)print(f"已将图像旋转 {angle} 度")return Trueexcept Exception as e:print(f"旋转图像时出错: {e}")return False# 使用示例
rotate_image('example.jpg', 'example_rotated.jpg', 90)  # 旋转90度

图像格式转换

Python Imaging Library允许你使用 convert() 方法在不同像素表示之间转换图像,同时可以通过保存时指定不同的扩展名来转换格式。

from PIL import Image
import osdef convert_image_format(input_path, output_format):"""转换图像格式Args:input_path: 输入图像路径output_format: 输出格式(如'png', 'jpg', 'webp'等)"""try:# 打开原始图像img = Image.open(input_path)# 获取文件名(不含扩展名)filename = os.path.splitext(os.path.basename(input_path))[0]# 构建输出路径output_path = f"{filename}.{output_format.lower()}"# 保存为新格式img.save(output_path)print(f"已将图像从 {os.path.splitext(input_path)[1]} 转换为 {output_format}")return output_pathexcept Exception as e:print(f"转换图像格式时出错: {e}")return None# 使用示例
convert_image_format('example.jpg', 'png')  # 将JPG转换为PNG
convert_image_format('example.jpg', 'webp')  # 将JPG转换为WebP

添加水印

from PIL import Image, ImageDraw, ImageFontdef add_text_watermark(input_path, output_path, text, position=None, color=(255, 255, 255, 128), font_size=40):"""添加文字水印Args:input_path: 输入图像路径output_path: 输出图像路径text: 水印文字position: 水印位置,格式为(x, y),默认为None(居中)color: 水印颜色,格式为(R, G, B, A),默认为半透明白色font_size: 字体大小"""try:# 打开原始图像img = Image.open(input_path).convert("RGBA")# 创建透明图层txt = Image.new('RGBA', img.size, (255, 255, 255, 0))# 获取绘图对象draw = ImageDraw.Draw(txt)# 加载字体try:font = ImageFont.truetype("Arial.ttf", font_size)except IOError:font = ImageFont.load_default()# 计算文本大小text_width, text_height = draw.textsize(text, font)# 如果未指定位置,则居中放置if position is None:position = ((img.width - text_width) // 2, (img.height - text_height) // 2)# 绘制水印文字draw.text(position, text, font=font, fill=color)# 合并图层watermarked = Image.alpha_composite(img, txt)# 保存结果watermarked.convert('RGB').save(output_path)print(f"已添加文字水印: '{text}'")return Trueexcept Exception as e:print(f"添加水印时出错: {e}")return Falsedef add_image_watermark(input_path, output_path, watermark_path, position=None, opacity=0.3):"""添加图像水印Args:input_path: 输入图像路径output_path: 输出图像路径watermark_path: 水印图像路径position: 水印位置,格式为(x, y),默认为None(右下角)opacity: 水印透明度,0-1之间"""try:# 打开原始图像和水印base_image = Image.open(input_path).convert("RGBA")watermark = Image.open(watermark_path).convert("RGBA")# 调整水印大小(可选,这里设为原图的1/4宽度)watermark_width = base_image.width // 4watermark_height = int(watermark.height * watermark_width / watermark.width)watermark = watermark.resize((watermark_width, watermark_height))# 调整水印透明度watermark_with_opacity = Image.new('RGBA', watermark.size, (0, 0, 0, 0))for x in range(watermark.width):for y in range(watermark.height):r, g, b, a = watermark.getpixel((x, y))watermark_with_opacity.putpixel((x, y), (r, g, b, int(a * opacity)))# 如果未指定位置,则放在右下角if position is None:position = (base_image.width - watermark_width - 10, base_image.height - watermark_height - 10)# 创建透明图层transparent = Image.new('RGBA', base_image.size, (0, 0, 0, 0))transparent.paste(watermark_with_opacity, position)# 合并图层watermarked = Image.alpha_composite(base_image, transparent)# 保存结果watermarked.convert('RGB').save(output_path)print(f"已添加图像水印")return Trueexcept Exception as e:print(f"添加水印时出错: {e}")return False# 使用示例
add_text_watermark('example.jpg', 'example_text_watermark.jpg', '© 2023 公司名称')
add_image_watermark('example.jpg', 'example_image_watermark.jpg', 'logo.png')

图像增强

Python Imaging Library提供了许多可用于增强图像的方法和模块。比如 ImageFilter 模块包含许多可以与 filter() 方法一起使用的预定义增强滤波器。

from PIL import Image, ImageEnhance, ImageFilterdef enhance_image(input_path, output_path, brightness=1.0, contrast=1.0, sharpness=1.0, color=1.0):"""增强图像Args:input_path: 输入图像路径output_path: 输出图像路径brightness: 亮度因子,1.0为原始亮度contrast: 对比度因子,1.0为原始对比度sharpness: 锐度因子,1.0为原始锐度color: 色彩因子,1.0为原始色彩"""try:# 打开原始图像img = Image.open(input_path)# 调整亮度if brightness != 1.0:enhancer = ImageEnhance.Brightness(img)img = enhancer.enhance(brightness)# 调整对比度if contrast != 1.0:enhancer = ImageEnhance.Contrast(img)img = enhancer.enhance(contrast)# 调整锐度if sharpness != 1.0:enhancer = ImageEnhance.Sharpness(img)img = enhancer.enhance(sharpness)# 调整色彩if color != 1.0:enhancer = ImageEnhance.Color(img)img = enhancer.enhance(color)# 保存增强后的图像img.save(output_path)print(f"已增强图像")return Trueexcept Exception as e:print(f"增强图像时出错: {e}")return Falsedef apply_filter(input_path, output_path, filter_type):"""应用滤镜Args:input_path: 输入图像路径output_path: 输出图像路径filter_type: 滤镜类型,如'BLUR', 'CONTOUR', 'SHARPEN'等"""try:# 打开原始图像img = Image.open(input_path)# 应用滤镜if filter_type == 'BLUR':filtered_img = img.filter(ImageFilter.BLUR)elif filter_type == 'CONTOUR':filtered_img = img.filter(ImageFilter.CONTOUR)elif filter_type == 'SHARPEN':filtered_img = img.filter(ImageFilter.SHARPEN)elif filter_type == 'EMBOSS':filtered_img = img.filter(ImageFilter.EMBOSS)elif filter_type == 'EDGE_ENHANCE':filtered_img = img.filter(ImageFilter.EDGE_ENHANCE)elif filter_type == 'SMOOTH':filtered_img = img.filter(ImageFilter.SMOOTH)else:print(f"未知滤镜类型: {filter_type}")return False# 保存处理后的图像filtered_img.save(output_path)print(f"已应用 {filter_type} 滤镜")return Trueexcept Exception as e:print(f"应用滤镜时出错: {e}")return False# 使用示例
enhance_image('example.jpg', 'example_enhanced.jpg', brightness=1.2, contrast=1.1, sharpness=1.3)
apply_filter('example.jpg', 'example_blur.jpg', 'BLUR')
apply_filter('example.jpg', 'example_sharpen.jpg', 'SHARPEN')

批量处理图像

import os
from PIL import Imagedef batch_process_images(input_folder, output_folder, process_func, **kwargs):"""批量处理图像Args:input_folder: 输入文件夹路径output_folder: 输出文件夹路径process_func: 处理函数**kwargs: 传递给处理函数的参数"""# 确保输出文件夹存在if not os.path.exists(output_folder):os.makedirs(output_folder)# 获取所有图像文件image_extensions = ('.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp')image_files = [f for f in os.listdir(input_folder) if os.path.isfile(os.path.join(input_folder, f)) and f.lower().endswith(image_extensions)]# 处理每个图像success_count = 0for image_file in image_files:input_path = os.path.join(input_folder, image_file)output_path = os.path.join(output_folder, image_file)try:# 调用处理函数result = process_func(input_path, output_path, **kwargs)if result:success_count += 1except Exception as e:print(f"处理 {image_file} 时出错: {e}")print(f"批量处理完成,成功处理 {success_count}/{len(image_files)} 个文件")return success_count# 定义一个简单的处理函数(调整大小)
def resize_for_batch(input_path, output_path, width, height):try:img = Image.open(input_path)img = img.resize((width, height))img.save(output_path)return Trueexcept Exception as e:print(f"处理 {input_path} 时出错: {e}")return False# 使用示例
batch_process_images('input_images', 'output_images', resize_for_batch, width=800, height=600)

使用OpenCV处理图像

OpenCV是一个功能更强大的计算机视觉库,适合更复杂的图像处理任务,如图像识别、特征提取、目标检测等。

安装OpenCV

pip install opencv-python

基本操作

import cv2
import numpy as np# 读取图像
img = cv2.imread('example.jpg')# 显示图像信息
print(f"图像形状: {img.shape}")  # 返回(高度, 宽度, 通道数)
print(f"图像大小: {img.size}")    # 返回像素总数
print(f"图像类型: {img.dtype}")   # 返回数据类型# 显示图像(仅在有GUI环境时有效)
cv2.imshow('Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()# 保存图像
cv2.imwrite('example_copy.jpg', img)

图像缩放

import cv2def resize_image_cv2(input_path, output_path, new_size):"""调整图像大小Args:input_path: 输入图像路径output_path: 输出图像路径new_size: 新尺寸,格式为(宽, 高)"""try:# 读取图像img = cv2.imread(input_path)# 调整大小resized_img = cv2.resize(img, new_size)# 保存调整后的图像cv2.imwrite(output_path, resized_img)print(f"已将图像从 {img.shape[1]}x{img.shape[0]} 调整为 {new_size[0]}x{new_size[1]}")return Trueexcept Exception as e:print(f"调整图像大小时出错: {e}")return False# 使用示例
resize_image_cv2('example.jpg', 'example_resized_cv2.jpg', (800, 600))

图像裁剪

import cv2def crop_image_cv2(input_path, output_path, crop_box):"""裁剪图像Args:input_path: 输入图像路径output_path: 输出图像路径crop_box: 裁剪区域,格式为(y_start, y_end, x_start, x_end)"""try:# 读取图像img = cv2.imread(input_path)# 裁剪图像y_start, y_end, x_start, x_end = crop_boxcropped_img = img[y_start:y_end, x_start:x_end]# 保存裁剪后的图像cv2.imwrite(output_path, cropped_img)print(f"已裁剪图像,裁剪区域: {crop_box}")return Trueexcept Exception as e:print(f"裁剪图像时出错: {e}")return False# 使用示例
crop_image_cv2('example.jpg', 'example_cropped_cv2.jpg', (100, 400, 100, 500))

图像旋转

import cv2
import numpy as npdef rotate_image_cv2(input_path, output_path, angle):"""旋转图像Args:input_path: 输入图像路径output_path: 输出图像路径angle: 旋转角度(逆时针)"""try:# 读取图像img = cv2.imread(input_path)# 获取图像中心点height, width = img.shape[:2]center = (width // 2, height // 2)# 创建旋转矩阵rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)# 计算新图像的边界abs_cos = abs(rotation_matrix[0, 0])abs_sin = abs(rotation_matrix[0, 1])new_width = int(height * abs_sin + width * abs_cos)new_height = int(height * abs_cos + width * abs_sin)# 调整旋转矩阵rotation_matrix[0, 2] += new_width / 2 - center[0]rotation_matrix[1, 2] += new_height / 2 - center[1]# 执行旋转rotated_img = cv2.warpAffine(img, rotation_matrix, (new_width, new_height))# 保存旋转后的图像cv2.imwrite(output_path, rotated_img)print(f"已将图像旋转 {angle} 度")return Trueexcept Exception as e:print(f"旋转图像时出错: {e}")return False# 使用示例
rotate_image_cv2('example.jpg', 'example_rotated_cv2.jpg', 45)  # 旋转45度

添加水印

import cv2
import numpy as npdef add_text_watermark_cv2(input_path, output_path, text, position=None, color=(255, 255, 255), thickness=2, font_scale=1.0):"""添加文字水印Args:input_path: 输入图像路径output_path: 输出图像路径text: 水印文字position: 水印位置,格式为(x, y),默认为None(居中)color: 水印颜色,格式为(B, G, R),默认为白色thickness: 文字粗细font_scale: 字体大小缩放因子"""try:# 读取图像img = cv2.imread(input_path)# 获取文本大小font = cv2.FONT_HERSHEY_SIMPLEXtext_size = cv2.getTextSize(text, font, font_scale, thickness)[0]# 如果未指定位置,则居中放置if position is None:position = ((img.shape[1] - text_size[0]) // 2, (img.shape[0] + text_size[1]) // 2)# 添加文字水印cv2.putText(img, text, position, font, font_scale, color, thickness)# 保存结果cv2.imwrite(output_path, img)print(f"已添加文字水印: '{text}'")return Trueexcept Exception as e:print(f"添加水印时出错: {e}")return Falsedef add_image_watermark_cv2(input_path, output_path, watermark_path, position=None, alpha=0.3):"""添加图像水印Args:input_path: 输入图像路径output_path: 输出图像路径watermark_path: 水印图像路径position: 水印位置,格式为(x, y),默认为None(右下角)alpha: 水印透明度,0-1之间"""try:# 读取图像和水印img = cv2.imread(input_path)watermark = cv2.imread(watermark_path, cv2.IMREAD_UNCHANGED)# 如果水印有Alpha通道,则分离if watermark.shape[2] == 4:# 分离BGR和Alpha通道bgr = watermark[:, :, 0:3]alpha_channel = watermark[:, :, 3] / 255.0alpha_channel = cv2.merge([alpha_channel, alpha_channel, alpha_channel])else:bgr = watermarkalpha_channel = np.ones(bgr.shape, dtype=bgr.dtype)# 调整水印大小(可选,这里设为原图的1/4宽度)watermark_width = img.shape[1] // 4watermark_height = int(watermark.shape[0] * watermark_width / watermark.shape[1])bgr = cv2.resize(bgr, (watermark_width, watermark_height))alpha_channel = cv2.resize(alpha_channel, (watermark_width, watermark_height))# 如果未指定位置,则放在右下角if position is None:position = (img.shape[1] - watermark_width - 10, img.shape[0] - watermark_height - 10)# 计算ROIx, y = positionh, w = bgr.shape[0], bgr.shape[1]roi = img[y:y+h, x:x+w]# 应用水印result = (1 - alpha * alpha_channel) * roi + alpha * alpha_channel * bgr# 将结果放回原图img[y:y+h, x:x+w] = result# 保存结果cv2.imwrite(output_path, img)print(f"已添加图像水印")return Trueexcept Exception as e:print(f"添加水印时出错: {e}")return False# 使用示例
add_text_watermark_cv2('example.jpg', 'example_text_watermark_cv2.jpg', '© 2023 公司名称')
add_image_watermark_cv2('example.jpg', 'example_image_watermark_cv2.jpg', 'logo.png')

图像增强和滤镜

import cv2
import numpy as npdef adjust_brightness_contrast(input_path, output_path, brightness=0, contrast=1.0):"""调整亮度和对比度Args:input_path: 输入图像路径output_path: 输出图像路径brightness: 亮度调整值,正值增加亮度,负值降低亮度contrast: 对比度调整因子,大于1增加对比度,小于1降低对比度"""try:# 读取图像img = cv2.imread(input_path)# 应用公式:新像素 = 对比度 * 原像素 + 亮度adjusted = cv2.convertScaleAbs(img, alpha=contrast, beta=brightness)# 保存结果cv2.imwrite(output_path, adjusted)print(f"已调整亮度和对比度")return Trueexcept Exception as e:print(f"调整亮度和对比度时出错: {e}")return Falsedef apply_filter_cv2(input_path, output_path, filter_type, kernel_size=5):"""应用滤镜Args:input_path: 输入图像路径output_path: 输出图像路径filter_type: 滤镜类型,如'blur', 'gaussian', 'median', 'bilateral'kernel_size: 核大小"""try:# 读取图像img = cv2.imread(input_path)# 应用滤镜if filter_type == 'blur':filtered_img = cv2.blur(img, (kernel_size, kernel_size))elif filter_type == 'gaussian':filtered_img = cv2.GaussianBlur(img, (kernel_size, kernel_size), 0)elif filter_type == 'median':filtered_img = cv2.medianBlur(img, kernel_size)elif filter_type == 'bilateral':filtered_img = cv2.bilateralFilter(img, kernel_size, 75, 75)else:print(f"未知滤镜类型: {filter_type}")return False# 保存结果cv2.imwrite(output_path, filtered_img)print(f"已应用 {filter_type} 滤镜")return Trueexcept Exception as e:print(f"应用滤镜时出错: {e}")return False# 使用示例
adjust_brightness_contrast('example.jpg', 'example_adjusted_cv2.jpg', brightness=30, contrast=1.2)
apply_filter_cv2('example.jpg', 'example_gaussian_cv2.jpg', 'gaussian')
apply_filter_cv2('example.jpg', 'example_bilateral_cv2.jpg', 'bilateral')

实际应用场景

场景一:产品图片批量处理

import os
from PIL import Image, ImageEnhancedef process_product_images(input_folder, output_folder, target_size=(800, 800), enhance=True):"""批量处理产品图片Args:input_folder: 输入文件夹路径output_folder: 输出文件夹路径target_size: 目标尺寸enhance: 是否增强图像"""# 确保输出文件夹存在if not os.path.exists(output_folder):os.makedirs(output_folder)# 获取所有图像文件image_extensions = ('.jpg', '.jpeg', '.png')image_files = [f for f in os.listdir(input_folder) if os.path.isfile(os.path.join(input_folder, f)) and f.lower().endswith(image_extensions)]print(f"找到 {len(image_files)} 个产品图片")# 处理每个图像for image_file in image_files:input_path = os.path.join(input_folder, image_file)output_path = os.path.join(output_folder, image_file)try:# 打开图像img = Image.open(input_path)# 创建白色背景background = Image.new('RGB', target_size, (255, 255, 255))# 调整图像大小,保持宽高比img_ratio = min(target_size[0] / img.width, target_size[1] / img.height)new_size = (int(img.width * img_ratio), int(img.height * img_ratio))img = img.resize(new_size, Image.LANCZOS)# 将图像居中放置在白色背景上offset = ((target_size[0] - new_size[0]) // 2, (target_size[1] - new_size[1]) // 2)background.paste(img, offset)# 增强图像if enhance:# 增加亮度enhancer = ImageEnhance.Brightness(background)background = enhancer.enhance(1.1)# 增加对比度enhancer = ImageEnhance.Contrast(background)background = enhancer.enhance(1.1)# 增加锐度enhancer = ImageEnhance.Sharpness(background)background = enhancer.enhance(1.2)# 保存处理后的图像background.save(output_path, quality=95)print(f"已处理: {image_file}")except Exception as e:print(f"处理 {image_file} 时出错: {e}")print("产品图片批量处理完成")# 使用示例
# process_product_images('product_images', 'processed_products')

场景二:批量添加水印

import os
from PIL import Image, ImageDraw, ImageFontdef batch_add_watermark(input_folder, output_folder, watermark_text, position=None, font_size=30, opacity=0.5):"""批量添加水印Args:input_folder: 输入文件夹路径output_folder: 输出文件夹路径watermark_text: 水印文字position: 水印位置,格式为(x, y),默认为None(右下角)font_size: 字体大小opacity: 水印透明度,0-1之间"""# 确保输出文件夹存在if not os.path.exists(output_folder):os.makedirs(output_folder)# 获取所有图像文件image_extensions = ('.jpg', '.jpeg', '.png')image_files = [f for f in os.listdir(input_folder) if os.path.isfile(os.path.join(input_folder, f)) and f.lower().endswith(image_extensions)]print(f"找到 {len(image_files)} 个图像文件")# 加载字体try:font = ImageFont.truetype("Arial.ttf", font_size)except IOError:font = ImageFont.load_default()# 处理每个图像for image_file in image_files:input_path = os.path.join(input_folder, image_file)output_path = os.path.join(output_folder, image_file)try:# 打开图像img = Image.open(input_path).convert("RGBA")# 创建透明图层txt = Image.new('RGBA', img.size, (255, 255, 255, 0))draw = ImageDraw.Draw(txt)# 计算文本大小text_width, text_height = draw.textsize(watermark_text, font)# 如果未指定位置,则放在右下角if position is None:position = (img.width - text_width - 20, img.height - text_height - 20)# 绘制水印文字draw.text(position, watermark_text, font=font, fill=(255, 255, 255, int(255 * opacity)))# 合并图层watermarked = Image.alpha_composite(img, txt)# 保存结果watermarked.convert('RGB').save(output_path)print(f"已处理: {image_file}")except Exception as e:print(f"处理 {image_file} 时出错: {e}")print("批量添加水印完成")# 使用示例
# batch_add_watermark('photos', 'watermarked_photos', '© 2023 公司名称')

场景三:图像格式批量转换

import os
from PIL import Imagedef batch_convert_format(input_folder, output_folder, target_format='webp', quality=85):"""批量转换图像格式Args:input_folder: 输入文件夹路径output_folder: 输出文件夹路径target_format: 目标格式,如'jpg', 'png', 'webp'等quality: 图像质量,1-100之间(仅对jpg和webp有效)"""# 确保输出文件夹存在if not os.path.exists(output_folder):os.makedirs(output_folder)# 获取所有图像文件image_extensions = ('.jpg', '.jpeg', '.png', '.gif', '.bmp')image_files = [f for f in os.listdir(input_folder) if os.path.isfile(os.path.join(input_folder, f)) and f.lower().endswith(image_extensions)]print(f"找到 {len(image_files)} 个图像文件")# 处理每个图像for image_file in image_files:input_path = os.path.join(input_folder, image_file)# 获取文件名(不含扩展名)filename = os.path.splitext(image_file)[0]output_path = os.path.join(output_folder, f"{filename}.{target_format.lower()}")try:# 打开图像img = Image.open(input_path)# 如果图像有透明通道且目标格式是JPG,则添加白色背景if img.mode == 'RGBA' and target_format.lower() == 'jpg':background = Image.new('RGB', img.size, (255, 255, 255))background.paste(img, mask=img.split()[3])  # 使用alpha通道作为maskimg = background# 保存为目标格式if target_format.lower() in ('jpg', 'jpeg'):img.convert('RGB').save(output_path, 'JPEG', quality=quality)elif target_format.lower() == 'webp':img.save(output_path, 'WEBP', quality=quality)else:img.save(output_path, target_format.upper())print(f"已转换: {image_file} -> {os.path.basename(output_path)}")except Exception as e:print(f"转换 {image_file} 时出错: {e}")print("批量格式转换完成")# 使用示例
# batch_convert_format('original_images', 'webp_images', 'webp', 85)

通过以上代码示例和应用场景,你可以轻松实现各种图像处理自动化任务,大大提高工作效率。无论是批量处理产品图片、添加水印,还是转换图像格式,Python都能帮你轻松应对。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/94928.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/94928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Beats与Elasticsearch高效数据采集指南

Beats 是 Elastic Stack 中的数据采集器,用于从各种来源(日志、指标、网络数据等)轻量级收集数据,而 Elasticsearch 是搜索和分析引擎,负责存储、索引和快速检索数据。二者结合可搭建强大的数据分析管道(如…

前端异常监控,性能监控,埋点,怎么做的

你想做的是一个 前端监控系统(Frontend Monitoring / RUM, Real User Monitoring),主要包括:异常监控(JS 报错、资源加载错误、Promise 未捕获异常)性能监控(白屏时间、首屏时间、页面加载时间、…

Kubernetes一EFK日志架构

前言:​ 在云原生时代,Kubernetes已成为容器编排的事实标准,它赋予了应用极高的弹性、可移植性和密度。然而,这种动态、瞬时的特性也带来了可观测性的新难题:当数以百计的Pod在节点间频繁创建和销毁时,传统…

Linux下的软件编程——网络编程(tcp)

重点:1.UDP和TCP区别2.TCP三次握手和四次挥手3.TCP粘包问题及解决办法4.TCP客户端和服务端的编程流程 TCP:传输层传输控制协议(流式套接字)1)TCP的特点1.面向数据流2.有连接(通信之前必须建立连接…

印度尼西亚数据源 PHP 对接文档

一、环境要求与配置 1. 系统要求 PHP ≥ 7.4扩展&#xff1a;cURL、JSON、OpenSSLComposer&#xff08;推荐&#xff09; 2. 安装依赖 composer require guzzlehttp/guzzle3. 基础配置类 <?php // config/StockTVConfig.php class StockTVConfig {const BASE_URL https://…

Maven核心用法

1.什么是Maven2.Maven的作用&#xff08;依赖管理、项目构建、统一的项目结构&#xff09;2.1 依赖管理2.2 项目构建2.3 统一的项目结构3.Maven的介绍IDEA中对应信息4.Maven的安装注意&#xff1a;需要解压到 没有中文 不带空格 的目录下5.IDEA中的Maven配置然后需要配置JD…

TypeScript:never类型

never类型是TypeScript中最特殊的类型之一&#xff0c;它表示永远不会发生的值。作为专业前端工程师&#xff0c;理解never类型对于编写类型安全的代码至关重要。1. never类型的核心概念定义&#xff1a;never类型表示永远不会出现的值&#xff0c;常见于&#xff1a;抛出错误的…

图数据库neo4j的安装

安装JDK Neo4j是基于Java的图形数据库&#xff0c;运行Neo4j需要启动JVM进程&#xff0c;因此必须安装JAVA SE的JDK。从Oracle官方网站下载 Java SE JDK&#xff0c;我的的版本是JDK8。 安装Neo4j 官网下载最新版本Neo4j 我下的是社区版的 Neo4j应用程序有如下主要的目录结构…

汽车诊断服务(UDS——0x27服务解析)

目录 1、服务概述 2、工作原理 3、常用的应用场景 4、子功能 5、请求与响应格式 5、1服务请求 5、2服务肯定响应 5、3服务否定响应 6、延时机制 1、服务概述 该服务对零部件中部分加密的服务进行解密工作安全访问的概念使用“种子”和“密钥”来实现 参数描述种子4字…

波兰密码破译机bomba:二战密码战的隐形功臣

本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我&#xff0c;一起撕掉过度包装&#xff0c;学习真实的AI技术&#xff01; 从数学原理到机械奇迹&#xff0c;破解enigma的早期利器 ✨ 1. bomba概…

【RAGFlow代码详解-30】构建系统和 CI/CD

Docker 构建系统 RAGFlow 使用主 Dockerfile 1-214 中定义的复杂多阶段 Docker 构建过程&#xff0c;该过程创建应用程序的完整和精简变体。 多阶段构建架构Docker 构建过程 构建过程由 Dockerfile 2-214 中 定义的三个主要阶段组成&#xff1a;基础阶段 &#xff08; Dockerfi…

rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(十七)设置主题

设置主题set_visuals ctx.set_visuals(Visuals::dark()); 设置暗色主题ctx.set_visuals(Visuals::light()); 设置亮色主题 fn main() -> eframe::Result<()> {// 配置原生窗口参数let options eframe::NativeOptions::default();eframe::run_simple_native("主题…

Linux入门教程 第十五章 Linux 系统调优工具

文章目录一、系统调优概述与 CPU 负载查看1.使用 uptime 查看系统负载2.使用 top 按 CPU 使用率排序3.使用 ps 查看 CPU 使用最多的进程4.使用 mpstat 查看 CPU 详细状态一、查看内存运行状态1.使用 free 查看内存使用2.查看 /proc/meminfo 获取详细内存信息3.使用 top 按内存使…

【Docker基础】Docker-compose进阶配置:健康检查与服务就绪

目录 引言 1 Docker健康检查基础概念 1.1 什么是健康检查 1.2 健康检查的状态 2 healthcheck配置详解 2.1 基本语法 2.2 配置参数解释 2.3 健康检查命令的编写 2.4 健康检查的工作流程 3 服务依赖与健康检查 3.1 depends_on的基本用法 3.2 结合健康检查的依赖 3.3…

Redis大Key处理流程与注意事项

概述 Redis大Key问题是在生产环境中经常遇到的技术挑战&#xff0c;它可能导致内存占用过高、网络延迟增加、阻塞其他操作等严重问题。本文将深入探讨Redis大Key的识别、处理流程以及相关注意事项。 什么是Redis大Key 定义标准 String类型: 单个Key的Value超过10KBHash类型: 单…

领悟8种常见的设计模式

很多 Java 初学者觉得设计模式 “抽象难学”&#xff0c;其实是没抓住核心逻辑 —— 设计模式不是 “炫技代码”&#xff0c;而是前辈们总结的 “解决高频复杂问题的通用思路”&#xff0c;好吧&#xff0c;你可以过一遍了解这些大概是个什么东西不求我们能够完全理解&#xff…

复杂BI报表SQL

复杂SQL 一行多个人员&#xff0c;平均瓜分总产量。 -- 西宁硅料三期 with b as ( select(row_number() OVER(PARTITION BY t1.tool ORDER BY t1.tool ) - 1) AS help_topic_id from((select1 AS tool union allselect1 AS tool union allselect1 AS tool union allselect1 AS …

bin log 和 redo log有什么区别

问题bin log 和 redo log有什么区别我的回答首先&#xff0c;这两种日志的作用不同。redo log是InnoDB引擎特有的&#xff0c;主要用于崩溃恢复&#xff0c;保证事务的持久性。而bin log是MySQL服务层的日志&#xff0c;主要用于主从复制和数据恢复。从层次上看&#xff0c;red…

导入文件允许合并表格

本来呢&#xff0c;已经有几年没咋写博客了&#xff0c;但是好像网上没什么好的合并导入可以抄的&#xff0c;周末加班了一天弄出来了&#xff0c;想一想也不算造轮子&#xff0c;可以露一手出来&#xff0c;最近也挺喜欢写注释的&#xff0c;应该方便大家抄的public class Tra…

WebIDEPLOY 技术驱动樱桃溯源管理系统的价值重塑与落地实践—— 以樱桃溯源管理系统构建产业信任体系的路径探索

一、WebIDEPLOY 技术支撑下的樱桃溯源系统核心架构樱桃种植从开花到销售的全流程数据记录&#xff0c;需要兼顾专业性与易操作性&#xff0c;WebIDEPLOY 技术以 “零代码降低门槛、云原生优化成本” 的特性&#xff0c;成为连接数字工具与樱桃种植的关键纽带。系统核心架构围绕…