Оптимизация картинок поворотом

Есть такой старый трюк, который с развитием CSS получил новое прочтение. Дело в том, что при упаковке изображения в графические форматы, в основном, сканируют и упаковывают изображение, двигаясь по его линиям слева направо. Первом об этом на русском языке написал, думаю, Лебедев, вот что написано в книге «Реактивные вебсайты», соавтором которой я являюсь:

Изображения GIF хорошо поддаются оптимизации. В параграфе №8 «Ководства» Артемия Лебедева есть небольшое, но интересное исследование особенностей этого формата. Вывод из параграфа простой: чем больше на картинке горизонтальных линий одного цвета, тем лучше сжимается изображение. Алгоритм компрессии LZW, применяемый в GIF, вообще лучше сжимает регулярные горизонтальные структуры в пределах одной линии.

Соответственно, если есть возможность повернуть картинку, то, бывает, она сжимается лучше. Где-то была хорошая статья с колесом на эту тему, не могу найти. Смысл там в том, что изображение с колесом можно поверкнуть как угодно, разницы нет, у колеса, поставленного на попа, нет «верха» и «низа», а вращение даёт возможность упаковать картинку эффективнее.

Но не всегда так везёт, гораздо чаще, согласитесь, встречаются изображения, которые повернуть нельзя. Значит о способе забываем?

Вот тут нам и пригодятся нововведения в ЦСС. Берём свою картинку, сохраняем ещё три копии повёрнутые на 90°, 180° и 270°, а потом все четыре изображения оптимизируем, выбираем то, которое меньше занимает. А дальше просто поворачиваем его при помощи ЦСС (я ещё фильтр для старых ИЕ добавил и некоторые свойства для других браузеров):

.rotate90 {
    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); /* IE 5.5+ */
    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; /* IE 8 */
    -ms-transform: rotate(90deg); /* IE 9 */
    -o-transform: rotate(90deg); /* Opera 10.5+ */
    -webkit-transform: rotate(90deg); /* Chrome, Opera 15+, Safari 3.1+, Android 2.1+, iOS 3.2+ */
    -moz-transform: rotate(90deg); /* FF 3.5+ */
    transform: rotate(90deg); /* FF 16+, IE 10+, Opera 12.1-14.99 */
}

Картинка поворачивается браузером и визуально остаётся как была.

Вообще, конечно, можно поворачивать на любой угол, если фон картинки прозрачный или совпадает с окружающим фоном, но в старых ИЕ для этого придётся использовать другой фильтр — Matrix, формула расчёта параметров такая:

progid:DXImageTransform.Microsoft.Matrix(
  M11 = cos(угол),
  M12 = -sin(угол),
  M21 = sin(угол),
  M22 = cos(угол),
  sizingMethod = 'auto expand'
);

Метод не лишён недостатков, конечно. Во-первых, всё это может сказаться на производительности, особенно в старых Эксплорерах (в последнем даже сомнений нет — скажется). Во-вторых, как видно из версий, которые я добавил в ЦСС, не все версии браузеров поддерживают поворот, правда их доля совсем невелика и продолжит снижаться.

15 комментариев

Работа из командной строки с модемом на Toshiba AC-100

Одна из задач, которую я хочу решить дома — слать СМС, если произошло что-то непредвиденное дома. Ближайшая задача — СМС, если уровень СО2 повысился выше нормы или произошло повышение температуры выше 40° (т. е. дома что-то горит).

С датчиком я определился, расскажу как-нибудь в другой раз, разбираюсь как можно отправить СМС по событию. У меня дома лежит не при деле смартбук Тошиба ЭйСи-100, на который я относительно недавно установил Линукс.

Что хорошо — у него есть 3Г-модем, а значит возможность слать СМС, осталось научиться это делать. Для начала надо найти как это устройство отображается в Линуксе. Нашёлся модем быстро, устройство F3307 — это модем фирмы Эрикссон (до названия идут какие-то странные спецсимволы):

Модем фирмы Эрикссон (43.48КиБ)

В логах видно, что это устройство «се́ло» на один из файлов /dev/ttyACM* (позднее испытания показали, что на первый):

Логи (26.19КиБ)

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

# Нужен баш версии 4 и выше
shopt -s lastpipe

function Say {
    echo -en "$1\r\n\0" > /dev/ttyACM1
    local line
    cat -v < /dev/ttyACM1 |
    while read -r line; do
        [ "$line" = OK^M ] && return 0
        [ "$line" = ERROR^M ] && return 1

        [ "$line" = ^M ] || echo "${line/%^M/}"
    done
}

# пример использования
Say AT+CGMI

В выходном потоке будет ответ модема, а в коде возврата — есть ли ошибка. Гугление показало, что отослать СМС при помощи команд очень просто, достаточно ввести две команды.

Теперь надо купить симку и попробовать.

20 комментариев