Компрессия PNG с PIL и CV2
Я пытаюсь сделать компрессор изображения в моем проекте Django. Я хорошо справился с JPG, но получил много проблем с PNG. Для сжатия я использую PIL и cv2, но не могу получить результат лучше, чем 16% сжатия для больших файлов PNG (>1 МБ). Я пытался объединить обе библиотеки, и это все еще не новшество. Вот простой код моего взгляда:
(приведенный выше код для сжатия JPG)
elif picture.mode == ('RGBA'):
if photo.image.size < 1000000:
colorsloss = picture.convert(mode="P", palette=Image.ADAPTIVE)
colorsloss.save('media/new/'+name,"PNG",quality=75, optimize=True, bits=8)
else:
originalImage = cv.imread(str('/home/andrey/sjimalka'+ photo.image.url))
cv.imwrite('media/new/'+name, originalImage,[cv.IMWRITE_PNG_COMPRESSION, 9])
cvcompressed = Image.open('media/new/'+name)
cvcompressed.convert(mode="RGB")
cvcompressed.save('media/new/'+name,"PNG",quality=75, optimize=True)
Итак, здесь у меня 2 большие проблемы: 1) Если у меня получилось изображение небольшого размера (< 1 мб), я использовал режим P в подушке. Это прекрасно работает, но если я сжимаю изображение с градиентом, я могу увидеть некоторые искажения в местах, где я получил градиент. У меня хорошее сжатие (что-то вроде 85%), но пока не знаю, как это исправить.
2) Я не могу получить хорошее сжатие больших файлов PNG. Моя лучшая цель - 16%, с действительно хорошим качеством, но это все еще не новшество. Мб я делаю что-то не так, или я должен использовать любую другую библиотеку или технологию, чтобы сделать это лучше. Я хочу получить список 50% сжатия с большими файлами PNG.
Я уже пытался использовать pngquant, но их документы были не слишком понятны для меня, и я не могу найти хорошие примеры кода.
1 ответ
PNG без потерь. Вы не можете отказаться от информации при записи, чтобы сделать файлы меньше, чем вы можете с помощью JPEG.
Если вы выбираете палитризованную версию, вам нужен только один байт на пиксель вместо трех, но тогда вы получите только 256 цветов, и градиенты будут выглядеть мусором.
Кроме того, настройка качества не такая, как для JPEG - это больше похоже на --fast
или же --best
параметр для gzip
,
Одна вещь, которую вы можете сделать, если у вас большие области прозрачности, как у вас, это сделать черными все пиксели, которые на 100% прозрачны. Это поможет им лучше сжиматься. Смотрите пример здесь.