Enlarge or shrink a set of images in the same directory to scale, such that the smaller of the height or width dimension is equal to targ.
    Note: 
    -- This function is multithreaded for efficiency. 
    -- When destination file or folder already exist, function exists without raising an error.

def resize_imgs(fnames, targ, path, new_path, resume=True, fn=None):
    """
    Enlarge or shrink a set of images in the same directory to scale, such that the smaller of the height or width dimension is equal to targ.
    Note: 
    -- This function is multithreaded for efficiency. 
    -- When destination file or folder already exist, function exists without raising an error. 
    """
    target_path = path_for(path, new_path, targ)
    if resume:
        subdirs = {os.path.dirname(p) for p in fnames}
        subdirs = {s for s in subdirs if os.path.exists(os.path.join(target_path, s))}
        already_resized_fnames = set()
        for subdir in subdirs:
            files = [os.path.join(subdir, file) for file in os.listdir(os.path.join(target_path, subdir))]
            already_resized_fnames.update(set(files))
        original_fnames = set(fnames)
        fnames = list(original_fnames - already_resized_fnames)
    
    errors = {}
    def safely_process(fname):
        try:
            resize_img(fname, targ, path, new_path, fn=fn)
        except Exception as ex:
            errors[fname] = str(ex)

    if len(fnames) > 0:
        with ThreadPoolExecutor(num_cpus()) as e:
            ims = e.map(lambda fname: safely_process(fname), fnames)
            for _ in tqdm(ims, total=len(fnames), leave=False): pass
    if errors:
        print('Some images failed to process:')
        print(json.dumps(errors, indent=2))
    return os.path.join(path,new_path,str(targ))