Як зменшити розмір файлу зображення за допомогою PIL


78

Я використовую PIL для зменшення розміру зображень там, перетворюючи більші зображення в менші. Чи існують якісь стандартні способи зменшити розмір файлу зображення, не втрачаючи при цьому занадто високої якості, скажімо, оригінальний розмір зображення становить 100 КБ, я хочу зменшити його до 5 або 10 КБ, особливо для форматів png та jpeg.


Що ви визначаєте як "занадто велику" втрату якості? Якщо ви хочете зменшити розмір файлу в 10-20 разів, найпростіший спосіб - зменшити кількість пікселів. Зменшення як ширини, так і висоти на 2/3 дасть вам зображення приблизно на 1/9 розміру оригіналу. Але це досить велика роздільна здатність, яку ви втрачаєте.
Роланд Сміт,

Відповіді:


132

Вбудованим параметром для збереження JPEG та PNG є optimize.

 >>> from PIL import Image
 # My image is a 200x374 jpeg that is 102kb large
 >>> foo = Image.open("path\\to\\image.jpg")
 >>> foo.size
  (200,374)
 # I 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,9 кб може здатися не так вже й багато, але понад сотні / тисячі фотографій це може скласти.

Тепер, щоб спробувати зменшити його до 5 кб до 10 кб, ти можеш змінити значення якості в опціях збереження. Використання якості 85 замість 95 в цьому випадку дасть: Неоптимізовано: 15,1 кб Оптимізовано: 14,3 кб Використання якості 75 (за замовчуванням, якщо аргумент пропущено) дасть: Неоптимізовано: 11,8 кб Оптимізовано: 11,2 кб

Я віддаю перевагу якості 85 з оптимізацією, оскільки на якість це не сильно впливає, а розмір файлу значно менший.


4
Оновлення імені методу ANTIALIAS: станом на 2.7.0 усі методи зміни розміру є ANTIALIAS, а справжнє (нове) ім’я для конкретного фільтра ANTIALIAS - LANCZOS. (
Ці

22

припустимо, у вас є модель під назвою 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)

сподіваюся, це допоможе тому, хто натрапить на це.


5

Головний менеджер зображень в PILIS 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)

. Пам'ятайте, ви все ще можете видалити цей біт коду та визначити новий розмір.


3

Див. Функцію мініатюр модуля зображень PIL. Ви можете використовувати його для збереження менших версій файлів у вигляді різних типів файлів, і якщо ви хочете зберегти якомога більше якості, розгляньте можливість використання ANTIALIASфільтра.

Крім цього, я не впевнений, чи є спосіб вказати максимально бажаний розмір. Ви, звичайно, можете написати функцію, яка може спробувати зберегти кілька версій файлу з різними якостями, поки не буде досягнуто певний розмір, відкидаючи решту і надаючи вам потрібне зображення.


1
чи є спосіб зменшити розмір файлу, підтримуючи розміри постійними esp. для форматів png.
Яшвант Кумар,

1
Якщо ви хочете зберегти однакові розміри, єдине, що ви можете спробувати, це встановити параметр якості під час збереження зображення. Перевірте цю відповідь
Cryptite

1
але атрибут якості не має різниці для форматів png.
Яшвант Кумар,

У такому випадку я боюся, що не знаю. Файли PNG традиційно більші за розміром завдяки формату стиснення. Чи є PNG обов’язковим? Якщо ні, ви не думали про те, щоб спробувати GIF?
Cryptite

Для PNG конвертуйте зображення в меншу кольорову палітру. Використовуйте опцію "біти" зі значенням <8 під час запису файлу.
Роланд Сміт,

0

Якщо у вас є файл PNG (1 МБ для 400x400 тощо):

__import__("importlib").import_module("PIL.Image").open("out.png").save("out.png")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.