从文件夹中获取图像,合并两个图像,然后将不同的图像输出到具有唯一文件名的新文件夹中

2024-04-24 22:22:05 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我有两个文件夹,一个包含不同颜色的衬衫,另一个包含徽标

我正在尝试拍摄shirts文件夹中包含的图像,并将它们存储到一个数组中。我想知道如何使用tkinter模块“存储”它们。但是有点困惑。我想能够做同样的标志。一旦存储在数组中,我想获取图像并将它们合并到每个衬衫/徽标颜色的每个可能的图像组合中更好的是,根据颜色指定哪些颜色应具有哪些徽标

在合并过程中,我希望它将衬衫图像和徽标图像调整为标准大小,并将徽标图像放置在衬衫图像上的特定位置

完成所有这些之后,我想将新图像导出到一个具有唯一名称的文件夹中(考虑添加shirt_n.jpg、n=1,2,3等的循环)

我试着把所有的东西都找出来,我确实找到了我想要的东西,但我不知道如何把它们组合起来工作

编辑:我有点想知道如何得到我想要的结果,但正如你在下面看到的,下面的代码非常简单,没有经过优化。我不知道如何优化,将其压缩成更少的代码行

# python imports
import os
from tkinter import Tk
from tkinter.filedialog import askopenfilename
from PIL import Image

Tk().withdraw()
imFile = askopenfilename()

print("What shade is the shirt? Dark or Light?")
respShade = input()
print("What's the logo location? Right or Left?:")
respLocation = input()
print("Color abriv. name?")
respName = input()

shirt = Image.open(imFile)
shirt_01 = shirt.resize((1200, 1800))
shirt_02 = shirt.resize((1200, 1800))
shirt_03 = shirt.resize((1200, 1800))

# For Dark Apparel
if "ark" in respShade:
    logo_hfwl = Image.open("images/logos/randazzo/hfox-wht.png")
    logo_hfwl = logo_hfwl.resize((150, 80))
    logo_hrtw = Image.open("images/logos/randazzo/htld-wht.png")
    logo_hrtw = logo_hrtw.resize((150, 80))
    logo3_rzwl = Image.open("images/logos/randazzo/rand-wht.png")
    logo3_rzwl = logo3_rzwl.resize((150, 80))

    if "lef" in respLocation:
        shirt_01.paste(logo_hfwl, (660, 660), logo_hfwl)
        shirt_02.paste(logo_hrtw, (660, 660), logo_hrtw)
        shirt_03.paste(logo3_rzwl, (660, 660), logo3_rzwl)

    elif "rig" in respLocation:
        shirt_01.paste(logo_hfwl, (410, 660), logo_hfwl)
        shirt_02.paste(logo_hrtw, (410, 660), logo_hrtw)
        shirt_03.paste(logo3_rzwl, (410, 660), logo3_rzwl)

    shirt_01.save('images/final/' + respName + '-hfwl.jpg')
    shirt_02.save('images/final/' + respName + '-hrtw.jpg')
    shirt_03.save('images/final/' + respName + '-rwl.jpg')

# For Light Apparel

if "ght" in respShade:
    logo_hfwl = Image.open("images/logos/randazzo/hfox.png")
    logo_hfwl = logo_hfwl.resize((150, 80))
    logo_hrtw = Image.open("images/logos/randazzo/htld.png")
    logo_hrtw = logo_hrtw.resize((150, 80))
    logo3_rzwl = Image.open("images/logos/randazzo/rand.png")
    logo3_rzwl = logo3_rzwl.resize((150, 80))

    if "lef" in respLocation:
        shirt_01.paste(logo_hfwl, (660, 660), logo_hfwl)
        shirt_02.paste(logo_hrtw, (660, 660), logo_hrtw)
        shirt_03.paste(logo3_rzwl, (660, 660), logo3_rzwl)

    elif "rig" in respLocation:
        shirt_01.paste(logo_hfwl, (410, 660), logo_hfwl)
        shirt_02.paste(logo_hrtw, (410, 660), logo_hrtw)
        shirt_03.paste(logo3_rzwl, (410, 660), logo3_rzwl)

    shirt_01.save('images/final/' + respName + '-hfwl.jpg')
    shirt_02.save('images/final/' + respName + '-hrtw.jpg')
    shirt_03.save('images/final/' + respName + '-rwl.jpg')

# shirt.save('images/final/change_me.jpg')
path = "images/final/"
path = os.path.realpath(path)
os.startfile(path)

此外,我还尝试查找如何将它们保存到具有唯一名称的文件夹中。无法直接找到任何东西。如果你能解释你的解决方案背后的思维过程,那将有助于我理解!非常感谢你


Tags: 图像imageopenfinalpastelogojpgimages
2条回答

可以使用os.listdir()函数搜索目录中的文件。尝试将此添加到代码中

from tkinter import filedialog, Tk
import os

root = Tk()
root.withdraw()
path = filedialog.askdirectory(master=root)

imported_images = []
for file in os.listdir(path):
    file_path = os.path.join(path, file)
    imported_images.append(file_path)

# An easier, one-liner for doing this is by the use of list comprehension.
# imported_images = [os.path.join(path, file) for file in os.listdir(path)]

# imported_images is now a list of all the file paths in the specified directory.

我相信使用askdirectory函数比粘贴它更简单

首先,我建议将图像组织如下:

├── logos      // all logos
├── shirts
│   ├── light  // light colored shirts 
│   └── dark   // dark colored shirts
├── final
│   ├── right  // all shirts with each logo on the right
│   └── left   // all shirts with each logo on the left

然后我们需要定义一个函数来读取目录中的所有图像,而无需获取用户输入。这就是为什么我认为我们根本不需要tkinter

def getImages(searchDir):
    """
    Returns a list with the paths of all images found in the given path
    """

    imagesPaths = []

    for root, directories, files in walk(searchDir):
        for file in files:
            if '.jpg' in file or '.png' in file:
                imagesPaths.append(path.join(root, file))
    
    print("Found images in '{}' = {}".format(searchDir, len(imagesPaths)))
    return imagesPaths

现在最重要的功能是将“.png”格式的徽标合并到“.jpeg”格式的衬衫上。此功能包括三个部分:

  • 第1部分:打开两个图像,然后将它们调整为所需的高度和宽度
  • 第2部分:将徽标粘贴到衬衫上(我们需要一个技巧,以便将颜色格式更改为RGBA)
  • 第三部分:获取两个文件的名称,然后将它们“粘合”在一起。你可以随意给你的图片命名,所以你可以随意改变这一步

这是该功能的主体:

def addLogo(shirtPath, logoPath, shift=(0,0), outPath="final"):    
"""
    Takes a background image and a foreground image add merge them.
    The foreground image can be scaled and be rotated. It can also 
    be put at an aribttatry location (x,y). 
    """
    
    img1 = Image.open(shirtPath).convert('RGBA')
    img2 = Image.open(logoPath).convert('RGBA')
    
    img1 = img1.resize((1200, 1800))
    img2 = img2.resize((150, 80))

    # paste img2 on top of img1
    shift1 = (0, 0)
    shift2 = shift
    blended = Image.new('RGBA', size=(1200, 1800), color=(0, 0, 0, 0))
    blended.paste(img1, shift1)
    blended.paste(img2, shift2, img2)

    # Save the image with a name combinig both images names
    name1 = getNameWithoutExtension(shirtPath)
    name2 = getNameWithoutExtension(logoPath)
    blended = blended.convert("RGB")
    blended.save("{}/{}_{}.jpg".format(outPath, name2, name1))

这是我在“final/left”文件夹中得到的结果示例。我有两件衬衫和三个标志,所以结果是六张照片

enter image description here

最后,这是全部代码

# python imports
from os import walk, path, rename, mkdir
from PIL import Image

# This is a generic function which gets all paths of images
def getImages(searchDir):
    """
    Returns a list with the paths of all images found in the given path
    """

    imagesPaths = []

    for root, directories, files in walk(searchDir):
        for file in files:
            if '.jpg' in file or '.png' in file:
                imagesPaths.append(path.join(root, file))
    
    print("Found images in '{}' = {}".format(searchDir, len(imagesPaths)))
    return imagesPaths


def getNameWithoutExtension(imagePath):
        name = path.basename(imagePath)
        return path.splitext(name)[0]

def addLogo(shirtPath, logoPath, shift=(0,0), outPath="final"):
    """
    Takes a background image and a foreground image add merge them.
    The foreground image can be scaled and be rotated. It can also 
    be put at an aribttatry location (x,y). 
    """
    
    img1 = Image.open(shirtPath).convert('RGBA')
    img2 = Image.open(logoPath).convert('RGBA')
    
    img1 = img1.resize((1200, 1800))
    img2 = img2.resize((150, 80))

    # paste img2 on top of img1
    shift1 = (0, 0)
    shift2 = shift
    blended = Image.new('RGBA', size=(1200, 1800), color=(0, 0, 0, 0))
    blended.paste(img1, shift1)
    blended.paste(img2, shift2, img2)

    # Save the image with a name combinig both images names
    name1 = getNameWithoutExtension(shirtPath)
    name2 = getNameWithoutExtension(logoPath)
    blended = blended.convert("RGB")
    blended.save("{}/{}_{}.jpg".format(outPath, name2, name1))


# Load all logo files
logos_array = getImages("logos")

# Load all light shirts
light_shirts_array = getImages("shirts/light")

#Load all dark shirts
dark_shirts_array = getImages("shirts/dark")

# Loop over light shirts and add each logo to each of them
for shirt in light_shirts_array:
    for logo in logos_array:

        # Paste on the left
        addLogo(shirt, logo, (410, 660), "final/left")
        
        # Paste on the right
        addLogo(shirt, logo, (660, 660), "final/right")

相关问题 更多 >