我正在使用PIL来调整图像大小,从而将较大的图像转换为较小的图像。有没有标准的方法可以在不太损失质量的情况下减小图像文件的大小?假设原始图像的大小为100kB。我希望将其缩小到5或10KB,特别是对于PNG和JPEG格式的图像。
我正在使用PIL来调整图像大小,从而将较大的图像转换为较小的图像。有没有标准的方法可以在不太损失质量的情况下减小图像文件的大小?假设原始图像的大小为100kB。我希望将其缩小到5或10KB,特别是对于PNG和JPEG格式的图像。
保存JPEG和PNG图像时的内置参数是optimize
。
from PIL import Image
foo = Image.open('path/to/image.jpg') # My image is a 200x374 jpeg that is 102kb large
foo.size # (200, 374)
# downsize the image with an ANTIALIAS filter (gives the highest quality)
foo = foo.resize((160,300),Image.ANTIALIAS)
foo.save('path/to/save/image_scaled.jpg', quality=95) # The saved downsized image size is 24.8kb
foo.save('path/to/save/image_scaled_opt.jpg', optimize=True, quality=95) # The saved downsized image size is 22.9kb
optimize
标志将对图像进行额外处理,以找到尽可能减小其大小的方法。1.9kb可能看起来不算多,但在数百/数千张图片中,它会逐渐累加。现在,为了将其缩小至5KB至10KB左右,您可以更改保存选项中的质量值。在这种情况下,使用85而不是95的质量值将产生以下结果:
未优化:15.1 KB
优化后:14.3 KB
如果参数被省略,则使用75的质量(默认值)将产生以下结果:
未优化:11.8 KB
优化后:11.2 KB
我更喜欢使用optimize和品质85,因为品质变化不大,文件大小会更小。
假设您有一个名为Book的模型,并在其上有一个名为'cover_pic'的字段, 在这种情况下,您可以执行以下操作来压缩图像:
from PIL import Image
b = Book.objects.get(title='Into the wild')
image = Image.open(b.cover_pic.path)
image.save(b.image.path,quality=20,optimize=True)
希望它能对任何遇到困难的人有所帮助。
ANTIALIAS
过滤器。PIL
中的主要图像管理器是Image
模块。from PIL import Image
import math
foo = Image.open("path\\to\\image.jpg")
x, y = foo.size
x2, y2 = math.floor(x-50), math.floor(y-20)
foo = foo.resize((x2,y2),Image.ANTIALIAS)
foo.save("path\\to\\save\\image_scaled.jpg",quality=95)
optimize=True
以进一步减小大小,但优化仅适用于JPEG和PNG格式的图像。
对于其他图像扩展名,您可以降低新保存的图像的质量。
您可以通过删除一些代码并定义图像大小来更改新图像的大小,只有仔细查看代码才能找到如何执行此操作。
我定义了这个尺寸:x, y = foo.size
x2, y2 = math.floor(x-50), math.floor(y-20)
这里只是为了展示通常使用横向图片的情况。对于竖向图片,您可以采取以下方式:
x, y = foo.size
x2, y2 = math.floor(x-20), math.floor(y-50)
记住,您仍然可以删除那段代码并定义一个新的尺寸。
math.floor
。例如,85-2
等于 83
。math.floor
只会将小数转换为整数(例如,84.912
变成了 84
)。如果你想将 浮点数 转换为 整数,只需编写类似于 x = int(84.912)
或 x = 84.912 // 1
的代码即可。 - Samuel Muldoon这段脚本可以减小图片的宽度和高度,同时保持其比例
,并且还可以减小图片大小。
有两个选项
,它们会执行相同的逻辑,第一个选项是我在django项目中使用的方法
,第二个选项是纯Python版的实现
。
你可以根据自己的需要改变TARGET_WIDTH
的值。
在Django models.py
中,图片保存后会再次被处理。
from PIL import Image
class Theme(models.Model):
image = models.ImageField(upload_to='theme_image/')
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
this_image = Image.open(self.image.path)
width, height = this_image.size
TARGET_WIDTH = 500
coefficient = width / 500
new_height = height / coefficient
this_image = this_image.resize((int(TARGET_WIDTH),int(new_height)),Image.ANTIALIAS)
this_image.save(self.image.path,quality=50)
没有Django,foo.py
文件:
from PIL import Image
this_image = Image.open("path\to\your_image.jpg")
width, height = this_image.size
TARGET_WIDTH = 500
coefficient = width / 500
new_height = height / coefficient
this_image = this_image.resize((int(TARGET_WIDTH),int(new_height)),Image.ANTIALIAS)
this_image.save("path\where\to_save\your_image.jpg",quality=50)
PIL
)已经过时,应使用Pillow
代替。 - Samuel Muldoonfrom PIL import Image
WIDTH = 1020
HEIGHT = 720
img = Image.open("my_image.jpg")
resized_img = img.resize((WIDTH, HEIGHT))
resized_img.save("resized_image.jpg")
修改图片分辨率 Pillow
from PIL import Image
size = 7016, 4961
im = Image.open("my_image.png")
im_resized = im.resize(size, Image.ANTIALIAS)
im_resized.save("image_resized.png", "PNG")
或者您可以使用
im_resized.save("image_resized.png", quality=95, optimize=True)
image = Image.open("input_file.png")
image = image.resize((WIDTH, HEIGHT)) #smaller width and height than the original
image.save("output_file.jpg", "JPEG", quality=95)
minimum_quality = 50 # recommended, but optional (set to 0 if you don't want it)
quality = 95 # initial quality
target = 100000 # 100 kb
while True:
output_buffer = io.BytesIO() # import io
image.save(output_buffer, "JPEG", quality=quality)
file_size = output_buffer.tell()
if file_size <= target or quality <= minimum_quality:
output_buffer.close()
break
else:
quality -= 5
image.save(output_image, "JPEG", quality=quality)
__import__("importlib").import_module("PIL.Image").open("out.png").save("out.png")