Изменение размера изображения в браузере, лучшее, чем наивысшее качество PIL - PullRequest
2 голосов
/ 19 марта 2019

Преамбула

Я отображаю изображение из серверной части Django в тег 26 x 26px (css) <img>.

Я могу сделать это двумя способами:

  1. Изменение размера на внутренней стороне (подушка) до 26x26 (обрезка для сохранения соотношения сторон)
  2. Отправьте полноразмерное изображение и позвольте CSS изменить размер

Выпуск

При использовании алгоритма LANCZOS для изменения размера и сохранения результата в формате Jpg со 100% качеством отображаемое изображение выглядит намного хуже, чем изображение, измененное в браузере.

enter image description here

Почему это так, и есть ли способ это исправить?


РЕДАКТИРОВАТЬ : тестирование на дисплее Retina

EDIT : Бикубика очень похожа на Ланцоша

enter image description here

Ответы [ 2 ]

1 голос
/ 20 марта 2019

В этой статье [1] говорится, что дисплеи Retina (дисплеи с высоким разрешением) будут пытаться отображать в 2 раза больше пикселей в той же области. Площадь, которая также измеряется в пикселях, пикселях, которые вы фактически объявляете в CSS.

Так вот откуда пришло мое замешательство. Решением было создать миниатюры в два раза больше отображаемого размера.

1 голос
/ 19 марта 2019

По моему опыту, PIL / Pillow (в дальнейшем просто «Pillow») может вести себя совсем иначе с маленькими изображениями, чем с большими - не только в операциях изменения размера, но и вообще - но так что вы могли бы также протестировать все методы Подушка предлагает, например:

# q.v. https://gist.github.com/fish2000/d85befaf289c664b6a9f44d1b56e57da#file-asscat-py-L129-L134

from PIL import Image

# q.v. PIL.Image constants of the same (yet uppercased) names:
interpolation_methods = frozenset({
                          "box",
                          "bilinear", "bicubic",
                          "hamming", "lanczos",
                          "nearest" })

def interpol(name):
    """ Return a PIL/Pillow image interpolation method constant by name """
    return getattr(Image, name.upper())

size    = (26, 26)
avatar  = Image.open(…) # load your source avatar image
methods = (interpol(method) for method in interpolation_methods)
scaled  = (avatar.resize(size, resample=method) for method in methods)

# you can save these out for more granular inspection:
previews = list(scaled)
for preview in previews:
    preview.show()

… имейте в виду, что Image.NEAREST может дать удивительно приличные результаты для небольших размеров - это так, и тот факт, что Pillow ни в коем случае не является Adobe® Photoshop ™, и, таким образом, на самом деле не может быть поручено копировать результаты, которые вы возможно, вышел из того же.

Но так, безразлично, масштабировать ли с помощью CSS (или любым другим клиентским методом): всегда лучше посылать меньше байт по сети, если это возможно - но это не значит, что это может не будет сделано. Лично я перфекционист, но если мне не хватает времени или денег, я не педантичен к этому.

...