【Python 实战】---- 使用 OpenCV 实现图片的批量压缩
1. 前言
在日常开发中,我们经常需要处理大量的图片文件,例如调整图片大小以适应不同的显示需求或减少存储空间。本文将介绍如何使用Python和OpenCV库来批量压缩图片,并对实现相同功能的技术进行对比分析。
2. 技术对比选择
- Pillow库: Pillow是Python Imaging Library (PIL) 的一个分支,提供了丰富的图像处理功能。与OpenCV相比,Pillow更专注于图像处理,API更加简洁易用。但是,OpenCV在处理计算机视觉任务时更加强大。
- ImageMagick: ImageMagick是一个功能强大的图像处理工具集,支持多种编程语言。它提供了命令行工具和编程接口,可以处理各种图像格式。与OpenCV相比,ImageMagick在处理复杂图像操作时更加灵活,但学习曲线较陡峭。
- OpenCV :之所以采用 OpenCV,是因为之前学习过 OpenCV,同时之前使用 Pillow 实现过【Python实战】 ---- 批量图片压缩,所以这次开发使用 OpenCV。
3. 实现分析
- 读取图片 : 使用
cv2.imread()
函数读取图片文件。如果图片无法读取,函数会返回None
,此时程序会输出错误信息并返回。 - 计算新高度 : 为了保持图片的宽高比,我们需要根据指定的宽度计算新的高度。公式为:
height = int(width * image.shape[0] / image.shape[1])
,其中image.shape[0]
是原图片的高度,image.shape[1]
是原图片的宽度。 - 调整图片大小 : 使用
cv2.resize()
函数调整图片大小。interpolation=cv2.INTER_AREA
参数用于指定插值方法,该方法在缩小图片时效果较好。 - 保存图片 : 使用
cv2.imwrite()
函数将调整大小后的图片保存到指定路径。
4. 压缩实现代码
实现图片压缩的核心代码:
python
import cv2
import os
def resize_image(input_path, output_path, width=600):
# 读取图片
image = cv2.imread(input_path)
if image is None:
print(f"无法读取图片: {input_path}")
return
# 计算新的高度以保持宽高比
height = int(width * image.shape[0] / image.shape[1])
# 调整图片大小
resized_image = cv2.resize(image, (width, height), interpolation=cv2.INTER_AREA)
# 保存图片
cv2.imwrite(output_path, resized_image)
print(f"已保存: {output_path}")
5. 批量处理实现
在主函数,用于遍历文件夹中的所有图片文件并调用resize_image
函数进行处理:
python
def main():
# 输入和输出文件夹路径
input_folder = "images"
output_folder = "output"
# 创建输出文件夹(如果不存在)
os.makedirs(output_folder, exist_ok=True)
# 遍历输入文件夹中的所有图片文件
for filename in os.listdir(input_folder):
if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
input_path = os.path.join(input_folder, filename)
output_path = os.path.join(output_folder, filename)
resize_image(input_path, output_path)
if __name__ == "__main__":
main()
6. 执行代码效果

7. 处理前图片
7.1 具体图片文件分辨率和大小

7.2 所有图片的大小

8. 处理后图片
8.1 具体图片文件分辨率和大小

8.2 所有图片的大小

9.总结
- 使用 OpenCV 库来批量压缩图片。通过
cv2.imread()
、cv2.resize()
和cv2.imwrite()
等函数,我们可以轻松实现图片的读取、调整大小和保存。 - 对比了其他实现相同功能的技术,如Pillow库和ImageMagick。在实际开发中,我们可以根据具体需求选择合适的技术来处理图片。
- 由于图片是给手机端使用,又担心图片的分辨率太低,导致在手机上展示效果不好,因此最后设置宽度是 600px,即便如此,也可以看出整体图片的总压缩将近15倍,当然具体的不能这么计算,但是在移动端访问的确解决了问题。