简体   繁体   English

Python中的多处理多层图像合并

[英]Multiprocessing multi-layered image merging in Python

I've spent a few hours searching stack and google for an answer to this and seem to get close but never quite get the answer.我花了几个小时在堆栈和谷歌上搜索这个问题的答案,似乎很接近但从来没有完全得到答案。 I feel like it's something simple in create_files but I'm just not getting it.我觉得它在create_files中很简单,但我就是不明白。

I'm trying to increase the speed of a program that gets a random image from numbered folders, and stacks them on top of each other with transparency using Pillow.我正在尝试提高程序的速度,该程序从编号的文件夹中获取随机图像,并使用 Pillow 将它们以透明度堆叠在一起。 Now as soon as you hit 18 folders, with 20 or so images in each, this can be quite slow at around 2 seconds per image on my M1 MacBook Pro.现在,只要您点击 18 个文件夹,每个文件夹包含 20 张左右的图像,在我的 M1 MacBook Pro 上每张图像大约需要 2 秒,这可能会非常慢。 I thought of using multiprocessing to speed things up, and I don't know if it's because my code is so reliant on for loop iterator variables, but I couldn't seem to get pool.map to work for me without differing errors.我想过使用多处理来加快速度,但我不知道是不是因为我的代码非常依赖 for 循环迭代器变量,但我似乎无法让 pool.map 为我工作而不会出现不同的错误。 I'll post a snippet of the relevant functions.我将发布相关功能的片段。 Any advice would be amazing, I'm sure it's a simple refactor, might still just be a bit too green with Python.任何建议都会很棒,我敢肯定这是一个简单的重构,对于 Python 来说可能还是有点太绿了。

The variables that some of the functions call are either the path to a folder, or an array of all of the image paths (image1 will be [0] image2 will be [1] etc).一些函数调用的变量要么是文件夹的路径,要么是所有图像路径的数组(image1 将是 [0] image2 将是 [1] 等)。

def save_file(img, counter):
    if not os.path.exists(f"{output_folder}"):
        os.makedirs(f"{output_folder}")
    img.save(f"{output_folder}/file_{counter}.png")


def create_composite(layer_count, img):
    image_size = Image.open(image_paths[0][0])
    composite_img = Image.new("RGBA", image_size.size)
    composite_img = merge_images(layer_count, img, composite_img)
    return composite_img


def merge_images(layer_count, img, composite_img):
    for i in range(layer_count):
        next_img = Image.open(img[i])
        composite_img = Image.alpha_composite(composite_img, next_img)
    return composite_img


def randomise_layers(layer_count):
    # Creates an array with randomised files for each layer and checks for exceptions.
    image_stack = []
    for i in range(layer_count):
        # Checks if there are any image conflicts and adds them to the stack.
        image_stack.append(check_exception(i))
    return image_stack


def check_exception(index):
    # Checks if any of the layers have a known exception with another layer
    temp_file_path = file_paths(index)
    if is_exception(temp_file_path):
        check_exception(index)
    else:
        return temp_file_path


def is_exception(file_path):
    # Gets layer exceptions from file
    return False


def create_files(iterations):
    for i in range(iterations):
        save_file(create_composite(layer_count, randomise_layers(layer_count)), i)
        if iterations < 10:
            print(f"File {i+1} created.")

if __name__ == "__main__":
    iterations = 5
    create_files(iterations)

OK!好的! So thanks to Albert's suggestion, I looked more into ProcessPoolExecutor, and did some refactoring.所以感谢 Albert 的建议,我更多地研究了 ProcessPoolExecutor,并做了一些重构。

my create_files function is now as follows:我的create_files函数现在如下:

def create_files(iterations):
    with concurrent.futures.ProcessPoolExecutor(os.cpu_count()-2) as exe:
        exe.map(save_file, list(range(iterations)))

Due to this refactoring and using map, I've had to move a bunch of variables to be global variables as I couldn't pass them into the functions onces the multiprocessing kicked in (seems to not hold onto any that have been declared in the same scope before).由于这种重构和使用映射,我不得不将一堆变量移动为全局变量,因为一旦多处理启动,我就无法将它们传递给函数(似乎没有保留任何已在之前的范围相同)。 I'll look more into passing some of those values into the threads, another alternative would be to make lists of those variables, and do something like我将更多地研究将其中一些值传递到线程中,另一种选择是列出这些变量,并执行类似的操作

var1 = [missing_variable] * iterations

to make them available.使它们可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM