#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 и использовать АДАПТИВНУЮ палитру. Если параметры не включены, ваш результат (при повторном преобразовании в палитру) будет зернистым. Также вы можете использовать параметр качества в функции сохранения для некоторых форматов изображений, чтобы еще больше улучшить качество.