В статье рассказывается о возможностях собственной реализации прогрессивной загрузки изображений на сайте без использования Flash. Интерактивное рисование реализуется через элемент: canvas из HTML5. Алгоритмическая основа процесса является дискретное вейвлет-преобразование.
Продолжение под катом.
Загружая браузером картинку в стандартном формате jpg, мы видим прорисовку сверху вниз, по мере поступления данных. Это самый простой пример прогрессивной загрузки. Не знаю по какой причине был проигнорирован вариант с прорисовкой из центра по спирали, актуальный для просмотра большинства фотографий. Дальнейшее развитие идея прогрессивной загрузки получила в стандарте progressive jpg. На просторах интеренета он встречается достаточно редко, хотя это формат поддерживают все основные браузеры и давно. Прорисовка происходит покадрово с ярко выраженной мозаичной структурой — особенности стандарта jpg. Мы попробуем пойти дальше и обратим внимание на формат jpeg2000. В отличие от jpg вместо косинусного преобразования в jpeg2000 используется вейвлет-преобразование, что дает большую степень сжатия при одинаковых показателях погрешности и меньшую блочность артефактов. Википедия утверждает, что он поддерживает прогрессивную загрузку с «рождения», но автору никогда не доводилось видеть это в действии. Более того, все примеры jpeg2000, которые удалось найти в интернете, открыть браузерами (Chrom 18, Explore 9, Firefox 11) не удалось. Сайт fileinfo.com, содержит информацию, что под Windows браузеры и не открывают формат jp2. Учитывая, что формат хоть и хороший, но его еще толком не поддерживают, и он может быть обременен скрытыми патентами, попробуем реализовать свою версию прогрессивной загрузки на основе вейвлет-преобразования.
Берем изображение, где высота и ширина равны степени 2 (ограничение алгоритма, как его обходить не будем рассматривать). В нашем случае это черно-белая карта с шириной и высотой 1024 пикселей. Пишем программу многоуровневого двумерного вейвлет-преобразования. Код прилагается: ссылка. Используется вейвлет Хаара, хотя в коде можно выбрать любой ортогональный вейвлет-фильтр и даже диадические вейвлеты, о которых обязательно будет написано, когда будет удачный пример применения. Кому нужно разобраться с алгоритмом или с самими вейвлетми, можно например взять книгу С. Малла Вейвлеты в обработке сигналов. Запускаем программу, указываем изображение. Получаем файлы txt, где хранятся отквантованные(нужно для уменьшения объема) вейвлет-коэффициенты с одинаковыми уровнями(в примере 5 уровней) и типами детализации. Загружаем их на сервер. Создаем html страничку с объектом canvas и в событие загрузки страницы пишем скрипт, поэтапной загрузки ранее созданных файлов вейвлет-коэффициентов. Каждый раз когда файл будет загружен, будет вызываться функция восстановления изображения (обратное вейвлет-преобразование). Смотрим, что получилось: ссылка_1(2 Mb). Сразу сознаюсь, что картинка загружается раз в 10 медленнее оригинала. Дело в том, что отквантованные коэффициенты были сохранены в файлы в виде текста и занимают на порядок больше места. Нужно было еще применить код Хафмана или полноценное сжатие коэффициентов. Браузер Explorer не желает выводить изменения в canvas пока идет выполнение скрипта. В Chrome дела обстоят чуть лучше, если вставить скажем alertы, то этапы будут видны(ссылка_2(2 Mb)). Если код будет выполняться «монотонно» то поведение схоже с Explorer. Радует предсказуемостью выполнения кода Firefox, чем и советую смотреть ссылку 1.
Можно с уверенностью сказать, что реализовать прогрессивную загрузку с помощью HTML5 можно, что современные браузеры сносно переносят трудоемкие математические вычисления (с современным компьютером). Остается открытым вопрос о своевременной визуализации произошедших в canvas изменений и актуальности темы прогрессивной загрузки вообще. Как отмечалось ранее, не так уж и часто можно заметить на сайте progressive jpg, а поддержки jp2 у браузеров и вовсе нет.
Автор: RedQuark