python 图片压缩,python压缩图片大小
由于图片的高度和宽度是强行定义的,所以会变形。我们希望图片大小改变后,比例不变,完成图片的压缩。下面文章主要介绍如何使用python批量压缩图片的相关信息。有需要的可以参考一下。
00-1010前言使用Python和Pillow模块压缩图片1、优化flag2、渐进式JPEG3、JPEG动态质量使用Python和Selenium模块操纵Squoosh批量压缩图片Python调用Selenium总结
目录
最近在研究如何无损压缩图像资源,也在网上找了一些资料。总而言之,我收获了很多,所以我想对我最近的学习做一个总结。
无损压缩其实是相对的,目的是在不影响图像显示质量的情况下,减少图像资源的内存大小。下面,我将介绍两种批量压缩图片的方法。第一种方法是使用python和Pillow模块压缩图片。这种方法对于jpeg图像具有非常高的压缩效率,但是这种方法不适合压缩png图像。另一种方式是使用Python和Selenium模块操纵Squoosh批量压缩图片。
前言
Pillow是Python中一个非常强大的图形处理库。如果本地没有安装,可以通过指令:pip install pill安装。使用枕头有三种压缩策略:1 .优化标志,2。渐进JPEG,3。JPEG的动态质量。
我们先写一个用Python保存图片的简单例子:
从PIL进口图片
从io导入StringIO
导入动态质量
im=Image.open(photo.jpg )
打印(即时格式、即时大小、即时模式)
new_photo=im.copy()
new_photo.thumbnail(im.size,resample=Image。抗锯齿)
save _ args={ format : im . format }
if im.format==JPEG:
save_args[quality]。值=85
new_photo.save(copy_photo.jpg ,**save_args)
使用Python和Pillow模块压缩图片
打开优化设置,以CPU时间为代价节省额外的文件大小。由于本质不变,对画质没有影响。
.
if im.format==JPEG:
save_args[quality]。值=85
save_args[optimize]=True
.
1、优化flag
当我们将图片保存为JPEG格式时,您可以从以下选项中选择不同的类型:
标准:JPEG图像从上到下加载。渐进:JPEG图像从模糊到清晰加载。渐进式选项可以在Pillow中轻松启用(progressive=True)。渐进式文件打包时,会有轻微的压缩。
.
if im.format==JPEG:
save_args[quality]。值=85
save_args[optimize]=True
save _ args[ progressive=True ]=True
.
2、渐进式JPEG
减小JPEG文件大小最广为人知的方法是设置质量。许多应用程序会在保存JPEG时设置特定的质量值。
质量其实是一个很抽象的概念。实际上,JPEG图像的每个颜色通道都有不同的质量。从0到100的质量等级对应不同颜色通道的不同量化表,这也决定了会损失多少信息。
信号域量化是JPEG编码中信号的损失。
息的第一个步骤。
我们可以动态地为每一张图片设置最优的质量等级,在质量和文件大小之间找到一个平衡点。我们有以下两种方法可以做到这点:
Bottom-up:这些算法是在 8x8 像素块级别上处理图片来生成调优量化表的。它们会同时计算理论质量丢失量和和人眼视觉信息丢失量。
Top-down:这些算法是将一整张图片和它原版进行对比,然后检测出丢失了多少信息。通过不断地用不同的质量参数生成候选图片,然后选择丢失量最小的那一张。
我们选择第二种方法:使用二分法在不同的质量等级下生成候选图片,然后使用pyssim计算它的结构相似矩阵 (SSIM) 来评估每张候选图片损失的质量,直到这个值达到非静态可配置的阈值为止。这个方法让我们可以有选择地降低文件大小(和文件质量),但是只适用于那些即使降低质量用户也察觉不到的图片。
下面是计算动态质量的代码dynamic_quality.py:
import PIL.Imagefrom math import log
from SSIM_PIL import compare_ssim
def get_ssim_at_quality(photo, quality):
"""Return the ssim for this JPEG image saved at the specified quality"""
ssim_photo = "tmp.jpg"
# optimize is omitted here as it doesnt affect
# quality but requires additional memory and cpu
photo.save(ssim_photo, format="JPEG", quality=quality, progressive=True)
ssim_score = compare_ssim(photo, PIL.Image.open(ssim_photo))
return ssim_score
def _ssim_iteration_count(lo, hi):
"""Return the depth of the binary search tree for this range"""
if lo >= hi:
return 0
else:
return int(log(hi - lo, 2)) + 1
def jpeg_dynamic_quality(original_photo):
"""Return an integer representing the quality that this JPEG image should be
saved at to attain the quality threshold specified for this photo class.
Args:
original_photo - a prepared PIL JPEG image (only JPEG is supported)
"""
ssim_goal = 0.95
hi = 85
lo = 80
# working on a smaller size image doesnt give worse results but is faster
# changing this value requires updating the calculated thresholds
photo = original_photo.resize((400, 400))
# if not _should_use_dynamic_quality():
# default_ssim = get_ssim_at_quality(photo, hi)
# return hi, default_ssim
# 95 is the highest useful value for JPEG. Higher values cause different behavior
# Used to establish the images intrinsic ssim without encoder artifacts
normalized_ssim = get_ssim_at_quality(photo, 95)
selected_quality = selected_ssim = None
# loop bisection. ssim function increases monotonically so this will converge
for i in range(_ssim_iteration_count(lo, hi)):
curr_quality = (lo + hi) // 2
curr_ssim = get_ssim_at_quality(photo, curr_quality)
ssim_ratio = curr_ssim / normalized_ssim
if ssim_ratio >= ssim_goal:
# continue to check whether a lower quality level also exceeds the goal
selected_quality = curr_quality
selected_ssim = curr_ssim
hi = curr_quality
else:
lo = curr_quality
if selected_quality:
return selected_quality, selected_ssim
else:
default_ssim = get_ssim_at_quality(photo, hi)
return hi, default_ssim
然后在下面的代码中引用计算动态质量的方法:
...if im.format==JPEG:
save_args[quality],value=dynamic_quality.jpeg_dynamic_quality(im)
save_args[optimize]=True
save_args[progressive]=True
...
使用Python和Selenium模块操纵Squoosh批量压缩图片
Squoosh 是谷歌发布的一款开源的图片在线压缩服务(伪),虽然需要用浏览器打开,但其实是一个整合了许多命令行工具的前端界面,调用的是本地的计算资源,所以只要打开过Squoosh一次,之后都会秒开,并且离线使用。不过最大的缺点就是不可以批量处理,如果我们要处理大量的图片资源,一张张地进行压缩处理将会消耗大量的人力成本和时间成本,这明显是不能接受的。我们要解决的问题就是写一个脚本来模拟浏览器的操作,使我们的双手得到解放。
Python 调用 Selenium
这是 Squoosh 的主界面,Select an Image 其实是一个输入框,那我们直接用 Selenium 把本地图片的路径输入进去就行了:
输入图片路径之后就会默认压缩成 75% 质量的 MozJPEG,我觉得无论是压缩比和质量都很不错,所以就没有改,等待页面加载完成之后就直接下载:
我们可以认为出现 "..% smaller" 就算是压缩完成,这时候直接点击右边的下载按钮即可。
代码:
from selenium import webdriverfrom selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
import os
import re
driver = webdriver.Chrome(C:/Users/admin/AppData/Local/Google/Chrome/Application/chromedriver.exe)
# 列出目录下所有的图片,存在 images 这个列表中
images = os.listdir(C:/Users/admin/Pictures/Saved Pictures)
# 处理所有图片
for i in range(len(images)):
# 构建图片路径
path = C:/Users/admin/Pictures/Saved Pictures/ + images[i]
# 尝试处理所有图片
try:
# 打开 Squoosh
driver.get(https://squoosh.app)
# 找到输入框
input_box = driver.find_element_by_xpath(.//input[@class="_2zg9i"])
# 输入图片路径
input_box.send_keys(path)
#设置图片格式
select1 = Select(driver.find_elements_by_css_selector(select)[-1])
if re.match(.*.png,images[i]):
select1.select_by_value("png")
if re.match(.*.jpg,images[i]):
select1.select_by_value("mozjpeg")
# 等待出现 smaller字样,10秒不出现则视为处理失败
locator = (By.XPATH, .//span[@class="_1eNmr _1U8bE"][last()])
WebDriverWait(driver, 25).until(EC.text_to_be_present_in_element(locator, smaller))
# 找到下载按钮
button = driver.find_elements_by_xpath(.//a[@title="Download"])[-1]
# 点击下载按钮
button.click()
# 输出处理失败的图片路径
except:
print(**30)
print(Error: + path + failed!)
print(**30)
continue
总结
到此这篇关于如何使用python对图片进行批量压缩的文章就介绍到这了,更多相关python图片批量压缩内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。