Оптимизация изображений без потерь

Smush.IT™ на локальном компьютере

Внимание: в данной статье описывается скрипт оптимизации изображений для . Если вы ищите программу для оптимизации изображений для Windows, то это PictureBeaver.

Один из советов по ускорению загрузки сайта, который даёт Yahoo! Exceptional Performance Team — это оптимизация изображений. без потерь (рассматриваться будет именно она) позволяет уменьшить размер изображений (временами очень даже значительно) и за счёт этого уменьшить общее время, требуемое для загрузки страницы.

Уменьшение размера изображения без потери качества достигается рядом способов:

  • использование другого алгоритма сжатия данных либо использование более агрессивных параметров (как правило, чем выше степень сжатия, тем больше времени уходит на );
  • удаление информационных блоков, наличие или отсутствие которых не влияет на декодирование изображения;
  • оптимизация цветов (например, если изображение сохранено в формате PNG32 — 4 байта на пиксель, но реально используются только 16 цветов — 4 бита на пиксель, то оптимизация цветов (color reduction) позволит значительно уменьшить размер файла).

Yahoo! предоставляет бесплатный сервис Yahoo! Smush.it™, который позволяет оптимизировать графику в онлайн-режиме, но его использование не всегда удобно. Гораздо удобнее, когда всё можно сделать на своём компьютере.

Нам понадобятся:

  • gifsicle для оптимизации GIF-изображений и анимаций;
  • optipng для оптимального сжатия PNG-файлов (что достигается путём перебора множества параметров, влияющих на работу алгоритма сжатия);
  • pngcrush для удаления лишних блоков из PNG-файла. Как и optipng, pngcrush умеет определять оптимальные параметры сжатия (optipng — это форк pngcrush), но, как показали тесты, у optipng это получается чуть лучше;
  • jpegtran позволяет выполнять преобразования без потерь над файлами JPEG (в частности, удаление лишних информационных блоков и перестраивание данных — коэффициентов дискретно-косинусного преобразования);
  • ImageMagick для определения формата изображений;
  • AdvanceCOMP позволяет достичь лучших результатов сжатия PNG-файлов, благодаря использованию реализации 7-Zip Defalte.

Весь этот зоопарк в дистрибутивах Linux, основанных на Debian, устанавливается так:

[-]
View Code Bash
sudo apt-get install advancecomp gifsicle optipng libjpeg-progs imagemagick pngcrush

Затем загружаем этот скрипт:

[-]
#! /bin/sh

if [ -z "$1" ]; then
    echo "Usage: optimize-image.sh filename"
    exit 1;
fi

if [ ! -f "$1" ]; then
    echo "$1 is not a file"
    exit 1;
fi

TYPE=`identify "$1" | grep -E -o 'JPEG|GIF|PNG'`
OLD=`stat -c %s "$1"`

case "$TYPE" in
    JPEG)
        jpegtran -copy none -optimize -perfect -progressive -outfile "$1.tmp" "$1"
        jpegtran -copy none -optimize -perfect -outfile "$1.tmq" "$1"
        if [ -f "$1.tmp" -a -f "$1.tmq" ]; then
            S_PROG=`stat -c %s "$1.tmp"`
            S_NORM=`stat -c %s "$1.tmq"`
            if [ $S_PROG -ge $S_NORM ]; then
                mv -f "$1.tmq" "$1"
                rm -f "$1.tmp"
            else
                mv -f "$1.tmp" "$1"
                rm -f "$1.tmq"
            fi;
        fi
    ;;

    GIF)
        gifsicle -O2 -b "$1"
    ;;

    PNG)
        pngcrush -q -rem alla -fix "$1" "$1.tmp"
        if [ -f "$1.tmp" ]; then
            mv -f "$1.tmp" "$1"
        fi;
        optipng -zc6-9 -zm1-9 -zs0-3 -f0-5 -q -fix "$1"
        advpng -z -4 -q "$1"
    ;;
esac

NEW=`stat -c %s "$1"`
echo "$1, old size: $OLD, new size: $NEW"

Файл должен быть исполняемым,так что не забываем ставить соответствующие права.

Для JPEG-файлов пробуется два разных способа кодирования: Progressive (низкочастотные коэффициенты находятся в начале файла) и обычное кодирование. В зависимости от изображение, Progressive JPEG может быть меньшим по размеру, чем non-progressive JPEG и наоборот.

Из PNG-файлов удаляются все лишние информационные блоки, после чего выполняется поиск оптимального варианта сжатия. Файл, сжатый optipng, обрабатывается advpng, который, в ряде случаев, позволяет достичь еще большего коэффициента сжатия.

GIF-файлы обрабатываются только gifsicle, я не добавлял код, который бы преобразовывал GIF в PNG и проверял, что лучше (так как в этом случае пришлось бы руками исправлять все ссылки на GIF-файл и заменять их ссылками на PNG).

Пример использования:

[-]
View Code Bash
find -type f \( -name "*.png" -o -name "*.gif" -o -name "*.jpg" -o -name "*.JPG" \) -exec optimize-image.sh '{}' \;

Внимание, перед использованием скрипта не забываем о необходимости резервного копирования! Хотя скрипт и тестировался в боевых условиях, осторожность никто не отменял.

Автор: ; опубликовано в: Linux; метки: Linux, оптимизация, сжатие
28
Ноя
2009

RSS Комментарии к статье «Оптимизация изображений без потерь» (15)  »

  1. Много интересного :) У меня есть похожая (хотя и не настолько продвинутая) штука для винды.

  2. dvigatelpr

    Картинки реально быстрее грузятся

  3. Скрипт действительно работает! И качество оптимизации нисколько не хуже чем Smush.it, причем в отличие от последнего можно запускать на произвольное количество вложенных каталогов сразу. 1000 файлов обрабатывается ~ за 5 минут, на средненькой машинке с ubuntu 8.04

  4. bur

    Добрый день
    Пытаюсь запустить скрипт под Fedora 8, консоль пишет

    ‘.sh: line 16: syntax error near unexpected token `in

    ЧДНТ

    • Есть подозрение, что файл, который Вы пытаетесь обработать, не является изображением GIG/PNG/JPG.

      Что выдает данная команда для того файла:

      identify имя_файла | grep -E -o 'JPEG|GIF|PNG'

  5. bur

    У меня bash не пониает команду identify

  6. Серж

    У меня Ubuntu 10.4 скрипт лежит здесь – /home/serg/
    Есть папка images, которую надо обработать,папка лежит здесь – /home/serg/
    Подскажите как завести скрипт. Выдает в терминале – find: `optimize-image.sh’: Нет такого файла или каталога
    Пробовал ему путь указывать перед optimize-image.sh – не помогает. Приведите пожалуйста пример использования с выборкой из конкретной папки.

    • У себя я скопировал скрипт в /usr/bin, выполняю так:

      [-]
      View Code Bash
      for i in *.gif *.png *.jpg; do optimize-image.sh "$i"; done

      optimize-image.sh должен быть исполняемым (не забываем про chmod +x); если скрипт у Вас находится на разделе /home, раздел должен быть смонтирован без noexec.

  7. bur

    Запускаю скрипт, а файлы не жмутся — размер остается прежним. Есть подозрения, что скрипт не работает, так как дата у файлов остается прежней. Запускаю из-под рута.

    screen.png

    • Судя по скрину, у Вас jpegtran не воспринимает какую-то из опций, судя по скриншоту — опцию -perfect

      Попробуйте

      [-]
      View Code Bash
      jpegtran -copy none -optimize -progressive -outfile test1.jpg test.jpg

      где test.jpg — Ваш тестовый файл.

      Если сработает, то удалите из строк скрипта

      [-]
      View Code Bash
              jpegtran -copy none -optimize -perfect -progressive -outfile "$1.tmp" "$1"
              jpegtran -copy none -optimize -perfect -outfile "$1.tmq" "$1"

      опцию -perfect.

  8. bur

    Еще вопрос: как запустить скрипт, чтобы он всю директорию uploads с поддиректориями прошел автоматом?

Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.

Оставить комментарий к записи «Оптимизация изображений без потерь»

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя

गते गते पारगते पारसंगते बोधि स्वाहा