如何为Python图片缩放脚本添加多线程?
问题修复方案
先列你代码里的几个致命问题,以及对应的修复方法:
1. 函数名写错了
你定义的处理函数是rescale,但代码里调用的是Upscale,这会直接触发NameError。把executor.submit(Upscale, i)改成executor.submit(rescale, i)即可。
2. 线程池设置不合理
max_workers=1000完全没必要,线程数远超过CPU处理上限,会导致线程切换开销剧增,反而拖慢效率。建议设置为CPU核心数的2-4倍,也可以用代码自动获取:
import os max_workers = os.cpu_count() * 2
3. rescale函数缺少放大逻辑
当前函数只是读取图片,没有执行放大操作。得补充缩放代码,还要记得保存处理后的结果:
def rescale(file): img = cv2.imread(file) # 以放大2倍为例,用INTER_CUBIC插值适合放大,画质更好 scaled_img = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) # 生成输出文件名,避免覆盖原文件 output_file = f"scaled_{file}" cv2.imwrite(output_file, scaled_img) return output_file
4. 未添加异常处理
如果某张图片损坏或不存在,future.result()会直接抛出异常导致程序崩溃。必须添加异常捕获:
for future in as_completed(future_to_response): file = future_to_response[future] try: result = future.result() print(f"处理完成:{result}") except Exception as e: print(f"处理{file}失败:{str(e)}") finally: t.update()
5. tqdm可以简化写法
不用手动维护计数器,直接用tqdm包装as_completed更简洁:
with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = [executor.submit(rescale, f) for f in file_list] for future in tqdm.tqdm(as_completed(futures), total=len(futures)): try: future.result() except Exception as e: print(f"处理出错:{str(e)}")
完整可运行代码
import cv2 import os import tqdm from concurrent.futures import ThreadPoolExecutor, as_completed def rescale(file): img = cv2.imread(file) if img is None: raise ValueError(f"无法读取图片:{file}") # 放大2倍,使用高质量插值算法 scaled_img = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) output_file = f"scaled_{file}" cv2.imwrite(output_file, scaled_img) return output_file file_list = ['page-136.jpg', 'page-0.jpg', 'page-11.jpg', 'page-12.jpg', 'page-13.jpg', 'page-14.jpg', 'page-37.jpg', 'page-58.jpg', 'page-62.jpg', 'page-64.jpg', 'page-134.jpg', 'page-135.jpg'] # 设置合理的线程数 max_workers = os.cpu_count() * 2 with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = {executor.submit(rescale, file): file for file in file_list} with tqdm.tqdm(total=len(futures)) as pbar: for future in as_completed(futures): file = futures[future] try: result = future.result() print(f"[{pbar.n+1}/{len(futures)}] 处理完成:{result}") except Exception as e: print(f"[{pbar.n+1}/{len(futures)}] {file} 处理失败:{str(e)}") finally: pbar.update(1)
内容的提问来源于stack exchange,提问作者user20658672
相关产品推荐
相关产品推荐

