如何将图像从多个目录复制到相应的多个目标目录并调整其大小?

时间:2018-12-07 08:29:56

标签: python loops image-processing

如何使用Python将多个子目录中存在的所有图像复制到与其对应的另一个子目录中?我有一个包含N个子文件夹的数据集主文件夹,每个子文件夹内有一组图像。我想对子目录中的每个图像进行处理,然后将其移动到相应的子目录中,就像创建新的数据集图像形式一样。像下面这样的树:

+Home-dir
----- +sub-dir1  --->img1,img2,img3,------imgN
----- +sub-dir2  --->img1,img2,img3,------imgN
----- +sub-dir3  --->img1,img2,img3,------imgN
..
----- +sub-dirN  --->img1,img2,img3,------imgN

我想得到以下内容:

+Home-dir-process
----- +sub-dir-new1  --->img-new1,img-new2,img-new3,------img-newN
----- +sub-dir-new2  --->img-new1,img-new2,img-new3,------img-newN
----- +sub-dir-new3  --->img-new1,img-new2,img-new3,------img-newN
..
----- +sub-dir-newN  --->img-new1,img-new2,img-new3,------img-newN

我可以将一个目录中的所有图像复制到相应的一个目录中,如下所示:

path1='path\to\before\processing\image'
path2='path\to\save\after\processing\image'
listing = os.listdir(path1)
for file in listing:
    im = Image.open(path1 + '\\' + file)
    img = im.resize((img_rows, img_cols))
    img.save(path2 + '\\' + file, "JPEG")

但是我想将多个子目录中的所有图像复制到另一个子目录中,有人可以帮我吗?

1 个答案:

答案 0 :(得分:0)

我修改了原始答案,因为它实际上并没有执行您想要的操作,基本上只执行了您问题中的代码所执行的操作-在单个文件夹中处理所有图像文件。

该驱动程序功能名为process_tree(),其功能是遍历主目录的子目录,以在其中查找与一组用户指定的文件名模式中的任何文件相匹配的文件,如果找到,创建目标子目录,然后在每个子目录上调用一个用户提供的函数,将现有的源文件名和所需的输出文件名以及用户希望的所有参数传递给该函数。

在下面的代码中,用户指定的示例函数名为resize_image()。顾名思义,它仅处理一个图像文件。

请注意,处理后的图像与源图像具有相同的名称(即,没有-_new后缀添加到其文件名中)。

import fnmatch
import os
from PIL import Image

verbose = True  # Global printing flag for vprint().


def process_tree(src, dst, patterns, processing_func, *args):
    vprint(' src: "{src}"'.format(src=src))
    vprint('dst: "{dst}"'.format(dst=dst))
    vprint()
    for dirpath, subdirs, filenames in os.walk(src, topdown=False):
        vprint('PROCESSING dirpath: "{}"'.format(dirpath))
        if dirpath == src:  # Root src directory?
            if not os.path.exists(dst):
                vprint('CREATING dst root: "{dst}"'.format(dst=dst))
                os.makedirs(dst)  # Make root dest folder.
            vprint()
            continue  # Don't process files in root folder.

        # Determine sub-directory of src being processed.
        src_subdir = os.path.relpath(dirpath, src)
        dst_subdir = os.path.join(dst, src_subdir)

        # Determine which files in dirpath match one or more of the patterns.
        if isinstance(patterns, str):
            patterns = (patterns,)  # Convert to single element sequence.
        processible = set(filename for pattern in patterns
                                    for filename in fnmatch.filter(filenames, pattern))
        if not processible:
            vprint('no files to process')  # Output directory not created.
        else:
            if os.path.isdir(dst_subdir):
                vprint('PROCESSING directory "{}"'.format(dst_subdir))
            elif os.path.exists(dst_subdir):
                raise NotADirectoryError('Non-drectory "{}" exists"'.format(dst_subdir))
            else:
                vprint('CREATING directory "{}"'.format(dst_subdir))
                os.makedirs(dst_subdir)

            vprint('processing files:')
            for filename in filenames:
                if filename in processible:
                    src_file_path = os.path.join(dirpath, filename)
                    dst_file_path = os.path.join(dst_subdir, filename)
                    try:
                        processing_func(src_file_path, dst_file_path, *args)
                    except Exception as exc:
                        vprint('  EXCEPTION processing file:\n    {!s}'.format(exc))
                        vprint()
            vprint()


def resize_image(src, dst, scale_factor):
    """ Resize image src by scale_factor and save result to dst. """
    vprint('resizing image:\n'
           '  src: "{src}"\n'
           '  scale factor: {scale_factor}'.format(**locals()))
    img = Image.open(src)
    # Calcuate new size.
    new_width = round(img.width * scale_factor)
    new_height = round(img.height * scale_factor)
    if new_width < 1 or new_height < 1:
        vprint('  width and/or height of scaled version of image "{filename}"\n'
               '  is less than 1 pixel - skipped'.format(filename=os.path.basename(src)))
        return
    resampling_method = Image.BICUBIC
    img = img.resize((new_width, new_height), resample=resampling_method)
    img.save(dst)
    vprint('  resized image saved to "{}"'.format(dst))

def vprint(*args, **kwargs):
    """ Only prints if global flag is set. """
    if verbose:
        return print(*args, **kwargs)

if __name__ == '__main__':

    inputpath  = r'\my\path\to\_source_images'
    outputpath = r'\my\path\to\_processed_images'

    process_tree(inputpath, outputpath, ('*.jpg',), resize_image, .5)