【问题标题】:Get images from folder(s), merging two images and then output variant image(s) into new folder w/ unique file names从文件夹中获取图像,合并两个图像,然后将变体图像输出到具有唯一文件名的新文件夹中
【发布时间】:2021-03-26 21:32:39
【问题描述】:

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

我正在尝试获取衬衫文件夹中包含的图像并将它们存储到一个数组中。我有点想知道如何使用 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)

另外,我尝试查找如何将它们保存到具有唯一名称的文件夹中。真的找不到任何真正直截了当的东西。如果您能解释解决方案背后的思考过程,那将有助于我理解!非常感谢!

【问题讨论】:

  • 抱歉,这个问题太宽泛了。它包含多个问题,甚至不完全清楚问题究竟出在哪里,因此它不适合这个网站。请将问题分解成更小的步骤,并提出多个更集中的问题,每个问题都清楚地说明您想要实现的目标。赏金在这里没有多大帮助。例如,如果唯一的问题是如何创建唯一的文件名,那么 [color]_[logo] 肯定就足够了。
  • 你必须使用 tkinter 吗?我建议你看看 OpenCV 库:docs.opencv.org/master/d6/d00/tutorial_py_root.html
  • 您使用的代码有什么问题。您是否只需要在复制完成后将其存储在新位置的帮助?
  • @CoolCloud 我不知道如何存储多个图像以在代码中调用,将它们组合成每个可能的组合,然后将它们保存为具有不同名称的多个图像。

标签: python python-3.x


【解决方案1】:

首先我建议将图片整理如下:

├── 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)
  • 第 3 部分:获取两个文件的名称,然后将它们“粘合”在一起。您可以随意命名您的图像,因此您可以根据需要随意更改此步骤。

这是这样一个函数的主体:

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”文件夹中得到的结果示例。我有两件衬衫和三个标志,所以结果是六张照片。

最后,这是完整的代码

# 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")

【讨论】:

    【解决方案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 函数比粘贴更简单。

    【讨论】:

      猜你喜欢
      • 2016-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-08
      • 2014-09-17
      相关资源
      最近更新 更多