html5
Работа с камерой и распознавание чисел в «Опере»

Я вчера заморочился на отличненько. Мне показалось скучным и грустным вводить цифры счёта за квартиру в окошко «Госуслуг» и решил сделать автоматическую распознавалку чисел, попутно изучив работу с камерой из браузера.
Доступ к камере — эксперментальный стандарт, поэтому мало кто из браузеров может им похвастаться, я использовал специальный билд «
АПИ оказалось несложным. Всё, что нужно сделать — соединить специальным образом тег VIDEO с источником стримового видео; потом я 10 раз в секунд забираю кадр с видео и кладу в CANVAS (на скриншоте он цветной), оттуда вырезаю небольшую область, перевожу в градации серого, беру за порог 75% от усреднённого цвета и перевожу всё в ч/б.
Больше всего из трёх часов, которые у меня ушли на это, я делал распознование цифр. Алгоритмы, которые я нашёл в интернете, были очень монструозными, да и переписывать готовое было скучно, поэтом я перепробовал несколько вариантов, которые пришли мне в голову.
В итоге, лучше всех распознаёт следующий алгоритм.
Сначала я очевидным образом разбиваю изображение на цифры, потом условно разделяю каждую цифру вертикальной линией по середине. Слева и справа от линий считаю количество переходов между чёрным и белым, двигаясь сверху вниз. Получаются комбинации из пар чисел. Я их прореживаю — одинаковые последовательно идущие заменяю на одно значение.
Получаются цепочки, которые уже достаточно хорошо характеризуют цифру, правда некоторые цифры этот паттерн не в состоянии распознать. Поэтому я считаю количетсво ч/б переходов ещё и по моей умозрительной вертикальной линии.
На скриншоте в большом текстовом поле записаны получившиеся комбинации. Первое — номер по порядку, далее (через двоеточие) — количество переходов по вертикали и потом описанная последовательность. Например, «ноль» записывается как «2:11» (два перехода по вертикали, потом одинаковые переходы по разу слева и справа разделительной линии).
Алгоритм «шумит»,
Черновики у меня в комментариях
Мне тут хочется пару проектов на PHP доделать, а я
В том числе сделал то, что давно просили — черновики в комментариях. Работает только в современных браузерах — IE 8.0+, FF 3.5+, Safari 4.0+, Chrome 4.0+, Opera 10.5+, а так же iOS 2.0+ и Андроид 2.0+. Только такой список, так как сохранение происходит в localStorage.
localStorage — это клиентская база данных «ключ и значение», которые есть сейчас уже во всех распространённых браузерах. Преимущество хранения черновиков именно в ней — черновик сохраняется вне зависимости от того рухнул сервер или нет, ведь localStorage сохраняет данные на диске клиента.
Кстати, я делал библиотеку эмуляции localStorage для IE 6 и 7 (используется behavior userData), но у себя использовать не буду, ни к чему поощрять некрофилию.
Работает всё следующим образом (детально можно посмотреть в исходниках любой страницы с комментариями): когда пользователь делает паузу в наборе комментария, мой JS вызывает localStorage.setItem, где ключём является URL страницы плюс имя поля (у меня их три — имя пользователя, сам комментарий и кому этот комментарий был адресова).
После отправки комментария в теле полученной страницы приходят вызовы localStorage.removeItem, которые удаляют сохранённые значения.
Наконец, если страница была загружена не в результате отправки комментария, вызываются localStorage.getItem, чтобы получить сохранённые значения и подставить их в соответствующие поля.
Код, с использованием JQuery, получился вот такой:
// globalStorage — это для FF 2.0, но я не уверен, что это правда работает
var storage = window.localStorage || window.globalStorage && window.globalStorage[location.hostname] || null;
if (storage) {
var savedraft = function s() {
if (s.hnd) {
clearTimeout(s.hnd);
}
var o = $(this);
s.hnd = setTimeout(function() {
try { // если не хватит места, будет исключение
var prefix = location.pathname + '#';
storage.setItem(prefix + o.attr('name'), o.val());
storage.setItem(prefix + '?', +new Date()); // сохраняю время, возможно в будущем буду подчищать старые черновики
} catch (o) {}
}, 500);
}
// каждый элемент, который надо сохранять, имеет класс draft
$.each($('.draft'), function(_, value) {
var o = $(value),
key = location.pathname + '#' + o.attr('name'),
v = storage.getItem(key);
if (savedsuccessfully) { // внешний флаг, что черновик больше не нужен — всё сохранено на сервере
storage.removeItem(key);
} else if (v !== null) {
o.val(v);
}
o.keypress(savedraft).change(savedraft);
})
}localStorage не резиновое, у разных браузеров значения различаются, но в целом, там около 5МБ на домен, да и диск пользователя забивать жалко. Поэтому я сохраняю время записи, возможно
localStorage для Internet Explorer 6 и 7
Написал небольшой класс в JavaScript для поддержки API localStorage в IE 6 и 7. localStorage — это браузерное хранилище
Доступ к значениям как к свойствам класса не реализован. Прежде всего потому, что в JS в этих версиях IE нет сеттеров и геттеров, а для того, чтобы воспользоваться onpropertychange мой объект надо поместить в DOM, что порождает массу гемороя, типа присутствия свойств из DOM, а не из хранилища.
Так же я не сделал события onstorage и onstoragecommit, потому что не придумал для чего это нужно (а второе корректно реализовать вообще нельзя).
Ещё не реализовал нестандартное, но полезное расширение remainingSpace, потому что в общем случае нельзя сказать сколько места ещё осталось в userData, так как квота зависит от зоны сайта (доверенная, интранет и так далее).
С большой вероятностью эта зона, конечно же, «интернет» (то есть квота 1МБ), но квоты localStorage сильно отличаются по механизму от userData, у последнего две квоты — на документ (в зоне «интернет» это 128КБ) и на домен (упомянутый мегабайт). Вполне может случится, что квота «на документ» ещё не исчерпана, а доменная уже да.
Зато я реализовал exception, который бросается в том случае, если IE говорит, что квота исчерпана.
В общем, основные вещи есть. Пример использования:
// .-~*´¨¯¨`*·~-.¸ тут подключаем библиотеку ,.-~*´¨¯¨`*·~-.¸
// записываем два значения
try {
localStorage.setItem('key1', 'myvalue1');
localStorage.setItem('key2', 'myvalue2');
} catch (e) {
if (e.description == 'QUOTA_EXCEEDED_ERR') {
alert('Нет места');
} else {
alert('Что-то не так, не знаю что.');
}
}
// смотрим значение по ключу «key1»
alert(localStorage.getItem('key1'));
// смотрим первое значение (по номеру), нумерация с нуля
alert(localStorage.key(0));
// удаляем значение по ключу «key1»
alert(localStorage.removeItem('key1'));
// смотрим сколько ключей осталось
alert(localStorage.length);
// очищаем хранилище полностью
alert(localStorage.clear());Ограничения на localStorage
localStorage —
Last time I’ve checked, Chrome 5.0.375.99 beta let me save
2600-2700 thousands of characters, Firefox 3.5.9 —5200-5300k, Explorer 8 —4900-5000k, and Opera 10.60 popped a dialog, letting me give the script unlimited storage.
Причём, я ещё заметил, что браузеры с разной скоростью выделяют место под хранилище. Некоторые («Опера», например, выделяет его за время O(1)), другие заметно замедляются с ростом размера выделяемой памяти.
Добавлено позднее: кстати. У объекта localStorage есть несколько методов, в тот же самый объект отображаются, как свойства, пары ключ/значение. В любом браузере, кроме FF, можно запросто перезаписать любой из методов этого объекта. Только FF предусмотрительно не позволяет этого делать. Жаль только, что он не позволяет этого делать молча, не выбрасывая exception.
Если читать стандарт, то ощущение такое, что авторы просто не учли этого случая и разрешают перезаписывать эти методы.
rel="noreferrer"
Как известно, около года назад в WebKit появилась поддержка атрибута «rel» у ссылки со значением «noreferrer». Если указать это значение, то браузер не будет передавать заголовок «referer», в котором указано с какого адреса браузер осуществил переход.
Это прекрасная вещь, которая позволяет защищать, к примеру, информацию из интранета. У нас (в «Яндексе») стоят специальные скрипты для скрытия заголовка «referer» специальными ухищрениями, чтобы предотвратить утечку (так как некоторые сервисы у нас с ЧПУ) данных. Этот атрибут, если он был бы реализован везде, решил бы эту задачу более изящно.
К сожалению, с его распространением, думаю, будет расти его параноидальное использование, что сильно повлияет на статистику. Сейчас можно быть
Ну и ещё один показатель бардака —
P.S. Возможно поддержка «noreferrer» и ещё
Motion JPEG или о чём я говорил
Некоторые ребята
Я лишь хотел обратить внимание на два факта:
- на бардак, когда формат видео не поддерживается тегом VIDEO ни в одном браузере, но поддерживается браузерами
- на то, что говорить «в браузерах нет единого формата видео» некорректно
И только.
Бардак: Motion JPEG (M-JPEG) и тег VIDEO
С утра, складывая носковый пасьянс (не сошёлся, три (!!!) разных носка) — жена постирала чёрное, я задумался о формате

Таким образом, вопреки всем разговорам, у нас уже есть единый потоковый видеоформат, de facto, причём есть давно. Правда, плохенький (напоминаю — каждый кадр целый JPEG) и проигрываемый немного
Бардак заключается в том, что тег VIDEO не поддерживает формат Motion JPEG ни в одном из браузеров. Это многое говорит о том как производители браузеров определяют вектор развития их детища. В погоне за модой забывают наводить порядок и править баги (красный круглый камень в дырочкой
Воспроизводится
При помощи тега CANVAS,
Можно, кстати, вспоминить, что Internet Explorer
Ещё более кстати, что этот плеер будет поддерживать видео в формате AVI и кодеки установленные в системе, так что если у вас в системе есть кодек
Canvas в IE9 будет
Ну что, AMD действительно тогда проговорилась, никакой ошибки нет — в IE9 будет CANVAS. Только что появился Internet Explorer 9 Platform Preview 3 и там есть CANVAS.
Должен сказать, скорость очень хорошая. Реализовано пока не всё (это
Кажется, с применением полупрозрачности (и тени) производительность IE9PP3 пока резко падает.
Из других новостей: AUDIO, VIDEO, CANVAS с аппаратным ускорением, увеличена производительность и улучшена его поддержка JavaScript, поддержка WOFF (формат шрифтов), ACID3 — 83%, HTML5 test — 84/300 (предыдущий результат — 32).
Unicode со «школотой»
HTML5 test
Автор теста HTML5 обновил свой тест, теперь максимальное количество очков, которое может набрать браузер — 300, а не 160. Кроме того, теперь поддержка браузером кодеков для тегов VIDEO/AUDIO не влияет на основные очки, а даёт бонусные. Это правильно, так как стандартном HTML5 кодек так и не выбран.
Результаты по браузерам выглядят так:
«Сафари» 5 — 208 (ночная сборка — 220) «Хром» 5 — 197 (ночная сборка — 217) FireFox 3.6 — 139 (ночная сборка — 176) «Опера» 10.50 — 129 (10.60a 3422 — 159) Internet Explorer 8 — 27 (IE9PP2 — 32)
То есть лидером, по результатам этого теста, является пока пятый «Сафари», при этом тот же пятый «Сафари» под Windows набирает только 165 очков.
«Опера» — ещё больше вещей из HTML5
Пока я тут ною, что «Опера» не поддерживает CSS1 в полном объёме, новый билд «Оперы» (10.60а build 3419) стал поддерживать кодек WebM для тега VIDEO (у которого есть все шансы стать стандартом), HTML5 offline web applications, Geolocation API (что давно было известно), Web Workers и
Круто, ребята, очень круто. Но сделайте поддержку CSS1 уже наконец.
Тег video и IE
Интересно, когда консорциум W3 отвернулся от тега OBJECT? Помнится, даже IFRAME старательно пытались заменить на OBJECT, а сейчас
Тем не менее, API ActiveX Windows Media Player хорошо документирован и работать с ним очень просто. Я в последнее время мало программирую на JavaScript и вчера вечером, чтобы освежить знания, попробовал сделал плеер, похожий на VideoJS, но только для IE — с тегом OBJECT и применением VML.

Сегодня утром решил не останавливатся на достигнутом и за завтраком начал делать другую
P.S. Некоторые вещи там сделаны неоптимально, так что я бы очень рекомендовал несколько подчистить код, если
P.P.S. Кнопочки и progress bar нарисованы через VML.
HTML5: события offline и online
На сайте JavaScript.ru появилась статья о новых событиях в JavaScript — offline и online (реализованы в Firefox 3.5 и Internet Explorer 8.0). Цитирую выводы:
Эти события никак не связаны с подключением к сети интернет и к сайту.
Они триггерятся при переходе по клику пользователя в автономный режим и обратно.
Они также триггерятся, когда отключаются все сетевые адаптеры, или подключается хотя бы один. При этом не важно, ведет ли он в реальный интернет.
Firefox глючит, в отличие от IE
Chromium 3: тег VIDEO
Вчера вышел очередной билд
А более меня поражает чем так полюбился разработчикам тег VIDEO. Из всего стандарта, кажется, это второе (первое — CANVAS), что стремятся реализовать в браузере. Opera и Safari реализовали, в FireFox 3.5 этот тег тоже уже есть. И вот теперь есть Chromium с поддержкой VIDEO. Я удивился, когда узнал, что IE8 вышел без него (тем более, что аналогичный тег там уже есть — IMG, он умеет проигрывать видео).
Правда по форматам видео полный разброд (вот что значит недописанный стандарт!): Opera и FireFox выбрали Theora, Safari — QuickTime, а Chromium — H.264.
Ogg и тег VIDEO, ActiveX Canvas для IE
Из других интересных новостей — Vladimir Vukićević разработал ActiveX для IE, который повторяет функциональность этого тега пока только частично, но работа продолжается. Тот же автор обещает в будущем поддержку тегов video и audio, тоже, видимо, в формате ActiveX.
HTML5 и IE
Оказывается, есть немного кривой, но способ заставить IE показывать незнакомые ему теги в глобальном namespace! В частности, это поможет уже сейчас использовать семантические теги из HTML5.
Решение основано на интересном хаке:
Btw, if you want CSS rules to apply to unknown elements in IE, you just have to do document.createElement(elementName). This somehow lets the CSS engine know that elements with that name exist.
Есть другое решение, но оно требует использования namespace. В IE есть всеми забытая технология custom tags. Когда появился черновик HTML5 я пытался использовать её, чтобы внедрить в документ новые теги:
<html xmlns:html5="http://www.w3.org/html/wg/html5/">
<head>
<style type="text/css">
html5\:footer {
display: block;
border: 1px solid black;
padding: 10px;
}
</style>
</head>
<body>
<html5:footer>This is footer!</html5:footer>
</body>
</html>Не совсем то, что нужно, если не использовать сторонние средства. Если использовать, то для альтернативного браузера можно оставлять как есть, а для правильных — вычищать ненужное пространство заменой на уровне
Далее дело техники. Например, если взять Nginx, в нём есть модули rewrite, browser и sub. Первый умеет выполнять условия, второй — определять браузеры, третий — заменять одну строку на другую. Получается
modern_browser msie 1.0;
if ($ancient_browser) {
sub_filter 'html5:' ''
}Надо сразу оговориться, что это не готовое решение, а намётки: кроме «html5:» надо так же вычистить «html5\:».
HTML5 VIDEO: кто первый? А так же 3D CANVAS
Вышел браузер «Сафари» версии 3.1,
Safari 3.1 is the first browser to support the new video and audio tags in HTML 5 and the first to support CSS Animations. Safari also supports CSS Web Fonts, giving designers limitless choices of fonts to create stunning new web sites
Что касается тега AUDIO — чистая правда, а с VIDEO — вышла накладка. Специальный билд «Оперы», поддерживающий этот тег, вышел
Кстати, самое интересное, что появилось в том билде «Оперы», это не тег VIDEO, а 3D Canvas — до этого момента тег CANVAS позволял работать только с примитивами на плоскости (отрезками, прямоугольниками, кругами и так далее), знаменитая игра «Canvascape», сделанная с применением этого тега (требует для работы любой браузер, поддерживающий CANVAS), просчитывае
Для 3D CANVAS задача вращения куба с текстурой, например — тривиальная. Примеров работы с этим новшеством пока немного, в оригинально статье упомянута Snake («змейка») в 3D, написанная Mathieu ’p01’ HENRI.
HTML 5 draft
Странно, но группа W3C анонсировала первый публичный черновой вариант спецификации HTML5. Предрекали, что черновая версия выйдет через пару лет, а сам стандарт — лет через 15. Видимо, счастье наступит раньше. Кстати, читая стандарт HTML5 понимаешь, что «семантическая вёрска» в HTML4 — фикция (к слову, чтобы два раза не вставать, вёрстка «дивами» в текущем состоянии — хак на хаке и такое же гуано как вёрстка таблицами, но сложнее и дороже). Надо будет
Easter Ogg
Из HTML5 официально исключены форматы Ogg Vorbis и Ogg Theora (предназначенные для использования проигрывания мультимедия в тегах AUDIO и VIDEO). Против формата выступали фирмы Nokia и Apple.
Напомню корень проблемы: в HTML есть стредство для внедрения рисунков и определены форматы (GIF, PNG, JPEG), которые гарантированно будут показываться во всех графических браузерах, но нет ничего подобного для видео и аудио. Нет единых форматов и средств управления проигрыванием из браузера через JavaScript. С появлением HTML5 ситуация должна быть исправлена появлением тегов VIDEO и AUDIO и введением стандартов кодеков, которые должны поддерживаться всеми браузерами.
Возможно, вместо форматов Ogg, будут использованы H.264
Так же ходят слухи, что основной причиной того, что форматы Ogg исключили, является то, что они не поддерживают DRM (средства для защиты авторских прав), это соображение возникло, большей частью
Тег VIDEO в новой «Опере»
Последний экспериментальный билд «Оперы» (ни в коем случае не устанавливайте его поверх вашей рабочей версии — эта версия основана на одной
Плохие новости заключаются в том, что этого тег, в текущей версии, доступен только для Windows, но в будущем обещают поддержку и остальных операционных систем.
Самое простое использование тега VIDEO — указание в атрибуте SRC видеофайла, который он должен проиграть и атрибута controls, который указывает должен ли браузер показывать кнопки управления воспроизведением (или разработчик будет управлять видео через соответствующие

Стандартные элементы управления (на рисунке) меня совершенно не впечатлили, я бы их использовать не стал, впрочем, дизайн ещё может измениться, да и всегда есть возможность сделать свои кнопки через JavaScript. Больше всего меня поразили методы внедрения видео в SVG — на сайте есть очень несложные в реализации примеры отражения шарика, движущегося внутри видео, в поверхности, наложения на видео фильтров (в примерах — trace edges, grayscale) и клиппинга.
P.S. На домашней странице Chris Double есть ссылки на FireFox3.0alpha9, собранный с поддержкой тега VIDEO.