我正在尝试使用 PIL 编辑指定目录(和子目录)内的所有图像,然后将编辑后的版本保存在不同的位置但在相同的子目录结构下。
即。输入:
Root directory
|
|---------Subdir 1
| |---Image_1
| |---Image_2
| |---Image_3
|
|---------Subdir 2
| |---Image_1
| |---Image_2
And Output:
{Specified directory}
|
|---------Subdir 1
| |---Edited_Image_1
| |---Edited_Image_2
| |---Edited_Image_3
|
|---------Subdir 2
| |---Edited_Image_1
| |---Edited_Image_2
子目录共享相同的名称,并在 os.walk 运行时创建。
我已将其构建为一个函数,以便稍后可以在 Linux 终端中运行它,并在调用该函数时更改选项。
from PIL import Image, ImageDraw, ImageOps
import os
from os.path import isfile, join
def editimage(image_directory="image_directory",
version="B", #Specify which version of ImageDraw edit to do
resize=False, #choose whether or not to resize image
new_size=(800,428), #choose new size
output_directory="output_directory"):
for directory, subdirs, files in os.walk(image_directory):
for dirname in subdirs:
if not os.path.exists(output_directory + dirname):
os.mkdir(output_directory + image_directory + dirname) #This does exactly what I want it to do
for directory, subdirs, files in os.walk(image_directory):
for f in files:
if f.endswith('.JPG'):
img = Image.open(directory + f)
draw= ImageDraw.Draw(img)
if version=="A":
draw.ellipse((1823, 1472, 2033, 1536), fill = (0,0,0), outline=None)
draw.rectangle((0, 0, 2048, 32), fill = (0,0,0), outline=None)
draw.rectangle((0, 1504, 2048, 1536), fill = (0,0,0), outline=None)
img=ImageOps.pad(img, size=(2731,1536), color="grey")
elif version=="B":
draw.rectangle((0, 1231, 2304, 1296), fill = (0,0,0), outline=None)
if resize==True:
img = img.resize(new_size)
else:
pass
img.save(output_directory + "/" + f + ".png")
这会让用户输入:
editimage("Path/to/input/", version="A", resize= False, output_directory="Path/to/output/")
我尝试使用
img.save(output_directory + subdirs + ".png"
或为此创建一个变量,但 Python 返回:TypeError: can only concatenate list (not "str") to list
,或者以其他方式希望输入目录位于输出目录中。它似乎并没有遍历每个子目录。
我以前用过
imagelist = [join(directory, f)
for directory, subdirs, files in os.walk(image_directory)
for f in files
if isfile
if f.endswith('.JPG')]
for f in imagelist:
img = Image.open(f) #etc..
构建读取和编辑图像,但是
img.save(f)
保留整个路径并且无法将图像保存到新位置。
函数的其余部分工作完美,如果我删除 img.save 行中的 output_directory 参数,它将覆盖原始目录(和子目录)中的图像。在意识到输出目录没有被使用之前我没有遇到任何问题。
因为版本A组图像在文件夹之间没有唯一命名,所以我需要能够重建目录路径。
我该如何解决这个问题? 谢谢!
下面的函数将为带注释的图像创建一个新目录,其树结构与输入目录相同。尽管您询问如何使用
pathlib
,我还是使用了核心 Python 库中的 os.walk()
。我喜欢它的面向对象方法,并发现代码更干净。 PEP248 提供了有关 pathlib 背后原理的更多详细信息。
from pathlib import Path
from PIL import Image, ImageDraw
def editimage(
image_directory="image_directory",
version="B", # Specify which version of ImageDraw edit to do
resize=False, # choose whether or not to resize image
new_size=(800, 428), # choose new size
output_directory="output_directory",
):
for jpg_file in image_directory.rglob("*.jpg"):
# Translate the input file path to the corresponding output file_path
relative_path = jpg_file.relative_to(image_directory)
output_file_path = output_directory / relative_path
# Create the output directory if it doesn't exist
output_file_path.parent.mkdir(parents=True, exist_ok=True)
# Annotate the image and save it (simplified example)
with Image.open(jpg_file) as img:
draw = ImageDraw.Draw(img)
draw.ellipse((0, 0, 300, 300), fill=(255, 0, 0), outline=None)
img.save(output_file_path)
editimage(
image_directory=Path("Path/to/input/"),
version="A",
resize=False,
output_directory=Path("Path/to/output/"),
)