Библиотека изображений Python: чистая понижающая дискретизация

#python #image #python-imaging-library #downsampling

#python #изображение #python-imaging-library #понижающая дискретизация

Вопрос:

У меня возникли проблемы при попытке заставить PIL корректно уменьшать дискретизацию изображений. Цель в этом случае состоит в том, чтобы мой веб-сайт автоматически выполнял понижающую дискретизацию -> кэшировал исходный файл изображения всякий раз, когда требуется другой размер, что избавляет от необходимости поддерживать несколько версий одного и того же изображения. Однако мне не повезло. Я пробовал:

 image.thumbnail((width, height), Image.ANTIALIAS)
image.save(newSource)
 

и

 image.resize((width, height), Image.ANTIALIAS).save(newSource)
 

и

 ImageOps.fit(image, (width, height), Image.ANTIALIAS, (0, 0)).save(newSource)
 

и все они, похоже, выполняют понижающую выборку ближайшего соседа, а не усредняют по пикселям, как это должно быть, поэтому изображения выглядят так

http://www.techcreation.sg/media/projects//software/Java Games/images/Tanks3D Full.png

Для

http://www.techcreation.sg/media/temp/0x5780b20fe2fd0ed/Tanks3D.png

что не очень приятно. Кто-нибудь еще сталкивался с этой проблемой?

Ответ №1:

Это изображение представляет собой изображение с индексированным цветом (палитра или режим P). Существует очень ограниченное количество цветов для работы, и вероятность того, что пиксель из измененного изображения окажется в палитре, невелика, поскольку для этого потребуется много промежуточных цветов. Поэтому при изменении размера он всегда использует режим ближайшего соседа; это действительно единственный способ сохранить ту же палитру.

Это поведение такое же, как в Adobe Photoshop.

Сначала вы хотите перейти в режим RGB и изменить его размер, а затем, при желании, вернуться в режим палитры перед сохранением. (На самом деле я бы просто сохранил его в режиме RGB, а затем отключил PNGCrush в папке с измененными размерами изображений.)

Комментарии:

1. Как вы определяете, имеет ли изображение индексированные цвета? Я знаю, что GIF-файлы всегда индексируются, но я думал, что PNG-файлы похожи на JPEG-файлы со сжатием без потерь, и поэтому использовал RGB, как и все остальные.

2. PNG может быть 8-битным индексированным цветом или 24-битным истинным цветом RGB. Тот, который вы опубликовали, проиндексирован. В этом случае режим изображения в PIL должен быть «P».

Ответ №2:

Этому более года, но на случай, если кто-то все еще ищет:

Вот пример кода, который увидит, находится ли изображение в режиме палитры, и внесет коррективы

  import Image # or from PIL import Image
 img = Image.open(sourceFile)
 if 'P' in img.mode: # check if image is a palette type
     img = img.convert("RGB") # convert it to RGB
     img = img.resize((w,h),Image.ANTIALIAS) # resize it
     img = img.convert("P",dither=Image.NONE, palette=Image.ADAPTIVE) 
           #convert back to palette
 else:
     img = img.resize((w,h),Image.ANTIALIAS) # regular resize
 img.save(newSourceFile) # save the image to the new source
 #img.save(newSourceFile, quality = 95, dpi=(72,72), optimize = True) 
    # set quality, dpi , and shrink size
 

Преобразовав палитру версии в RGB, мы можем изменить ее размер с помощью сглаживающего псевдонима. Если вы хотите преобразовать его обратно, вам нужно установить для dithering значение NONE и использовать АДАПТИВНУЮ палитру. Если параметры не включены, ваш результат (при повторном преобразовании в палитру) будет зернистым. Также вы можете использовать параметр качества в функции сохранения для некоторых форматов изображений, чтобы еще больше улучшить качество.