Структура данных на datamatrix коде. Коды стандарта Data Matrix. Через мобильный телефон

Обслуживание клиентов 28.07.2019

Одним из представителей 2D-баркодов является DataMatrix. Описан в международном стандарте ISO/IEC 16022:2006. Он позволяет закодировать до 3Кб информации. DataMatrix содержит избыточную структуру, которая позволяет восстановить до 30% полезной информации при частичном повреждении кода. Все коды используют коррекцию ошибок стандарта ECC200, который, в свою очередь, использует алгоритм Рида-Соломона(Reed-Solomon) для кодирования/декодирования данных.

Большинство DataMatrix-ов квадратные, но в целом можно использовать и прямоугольные коды. Кодируемые данные располагаются внутри прямоугольного шаблона, представляющего собой L-образный угол для ориентации считывающего устройства, и набор чередующихся чёрных и белых модулей по периметру символа.

Самым существенным достоинством Data Matrix является возможность на минимальной площади закодировать небольшие последовательности данных (до 10 символов). Это преимущество объясняется тем, что в Data Matrix содержится очень мало служебной информации, описывающей размеры и структуру данных штрихового кода.

DataMatrix применяется в основном для маркировки небольших объектов, например, микросхем, позволяя закодировать 50 символов в изображении размером 2-3 мм2.

Данная символика популярна в таких сферах применения как:

  • медицинская промышленность;
  • почтовые перевозки;
  • электронная промышленность;
  • автомобилестроение;
  • пищевая промышленность;
  • авиакосмическая и оборонная промышленность;
  • энергетическое машиностроение.

Наиболее нестандартное использование кода Data Matrix придумал сотовый оператор Vodaphone. Им было создано приложение для продажи электронных билетов с мобильных телефонов – купленный билет, кодируется Data Matrix и отсылается на сотовый телефон в виде картинки SMS, MMS или EMS сообщением.

Data Matrix адаптирован под считывание видео-системами. Другими словами, считывателями данного кода могут служить видеокамеры со встроенными декодирующими программами, а также ручные и стационарные сканеры, оснащенные внутренними и программными декодерами. Расстояние считывания зависит от таких факторов, как разрешение, размер кода и вид используемого оборудования. В зависимости от них оно может варьироваться от 0 мм до 91 см.

Способы нанесения Data Matrix:

  • Методом прямой печати на изделии:
    • струйной печатью
    • лазерной гравировкой
    • гравировкой иглами
  • Печатью на бумажных и полипропиленовых материалах при помощи:
    • Термо- и термотрансферных принтеров
    • Матричных принтеров
    • Струйных принтеров
    • Лазерных принтеров
  • Технология Data Matrix подходит для интеграции в существующие системы, например, для его нанесения можно применять готовые приложения по (Bar Tender) и SDK, а для считывания – модели сканеров, с физическим или программным интерфейсом «разрыв клавиатуры».

    Преимущества Data Matrix:
  • За счет того, что код имеет небольшие размеры, можно использовать меньшие этикетки, а значит сократить стоимость затрат на расходные материалы.
  • Можно колировать большой объем информации (например, помимо основных данных, включить такие как ID производителя, серийный номер товара и др.).
  • Код считывается независимо от его ориентации относительно считывателя, что ускоряет процесс идентификации.
  • Маркировка может наноситься непосредственно на само изделие.
  • Крупные пользователи Data Matrix:
  • Intel
  • Mercedes Benz
  • Siemens
  • Philips
  • Vodaphoone
  • Вас так же могут заинтересовать следующие товары.

    Во всём мире уже довольно давно используются так называемые Bar-коды, да-да это такие картинки с полосочками разной длины и толщины, которые приклеены к товарам в ближайшем супермаркете ^_^ Вообще, Bar-коды бывают разные, для нас же наиболее интересным будет так называемый QR-код (от Quick Response - Быстрый Отклик), наиболее широко распространившийся в интернете. Это двухмерный код, в отличии от полосочек на товарах, отсюда его очень важное свойство: информационная ёмкость. В общем, не буду цитировать википедию, кому интересно, сами прочитают. Существует достаточно большое число способов представления QR-кодов в Web, самые распространённые основаны на генерации картинок на стороне сервера. Однако, мои читатели знают, как мне не нравятся такие решения.

    Кратко о Bar-кодахQR-код

    Существует 4 основных класса представления информации посредством QR-кода , отличающиеся видом хранимых данных и максимальным объёмом:

    • Только цифровая информация - до 7089 цифр
    • Алфавитно-цифровая информация - до 4296 символов
    • Двоичные данные (8-битные байты) - до 2953 байт
    • Кандзи/Кана - до 1817 иероглифов

    QR-код имеет следующие уровни корекции ошибок, характеризующиеся объёмом информации для восстановления (от большего к меньшему):

    • H(igh) - 30%
    • Q(uality) - 25%
    • M(edium) - 15%
    • L(low) - 7%

    Алгоритм коррекции ошибок основан на коде Рида-Соломона .

    Кроме того, существует несколько версий представления данных (1-40), которые отличает максимальный объём хранимой информации и, соответственно, размер матрицы.

    DataMatrix код

    Это другой тип двумерного кода, менее распространённый в интернет, но более компактный. Код также предусматривает хранение информации для восстановления до 30%. В отличии от QR область нанесения не обязательно должна быть квадратной.

    Итак, приступим

    Мне конечно же не хотелось писать реализацию алгоритма генерации кодов, поэтому погуглив, нашел вполне подходящую реализацию кодирования на JavaScript от Kazuhiko Arase http://www.d-project.com/qrcode/index.html . Здесь реализован только один тип кодирования: 8-битными байтами, то есть любые данные разбираются как есть на байты, в этом же виде они считываются сканнерами. Такми образом мы можем кодировать любую строку в юникоде и любой вменяемый сканнер должен правильно её декодировать. Кроме того в данной реализации поддержка стандарта осуществлена до версии 10 включительно.

    Немного погодя мне попался jQuery плагин , основаный на этой разработке доблестного японца https://github.com/jeromeetienne/jquery-qrcode . Но представление в нём было реализовано исключительно посредством Canvas , а суровые разработчики обязаны писать кросс-браузерно там, где это только возможно.

    С DataMatrix кодами всё остояло сложнее, пока мне не попался jQuery плагин BarCode http://barcode-coder.com/en/barcode-jquery-plugin-201.html , который как раз таки содержал кодировщик DataMatrix от HOUREZ Jonathan . Однако сам по себе плагин показался мне слишком монструозным и труднорасширяемым, для того, чтобы как-то использовать его.

    Реализация

    Итак было решено реализовать различные движки рендеринга Bar-кодов в зависимости от поддержки на стороне клиента тех или иных возможностей, также поддержку различных типов кодировщиков:

    ;(function($){ var $$ = $.barcode = { defs: { // Опции по умолчанию type:false // Тип кода }, clas: "bar-code", // CSS класс conv: function(s){ // Функция преобразования строк return unescape(encodeURIComponent(s)); }, type: {}, // Типы кодов engine: {} // Рендереры }, T = function(t){ // Валидатор типа кода if(!$$.type[t]){ for(var i in $$.type){ t = i; break; } } return t; }, R = Math.floor; // Функция округления $.fn.bar_code = function(opts){ // Реализация плагина return this.each(function(){ var self = $(this); if(!self.hasClass($$.clas)){ self.addClass($$.clas); // Установка класса } var opt = $.extend(true, { // Инициализация опций width: self.innerWidth(), height: self.innerHeight(), text: self.text() }, $$.defs, opts), gene, inst, val = $$.conv(opt.text); // Преобразование данных opt.type = T(opt.type); // Init type self.empty(); if(!(gene = $$.type)){ // Нахождение кодера return; } if(!(inst = gene.init(opt, val))){ // Инициализация экземпляра кодера return; } var cnt = gene.read.call(inst), // Размеры матрицы est = [ // Размеры элемента матрицы R(opt.width/cnt), R(opt.height/cnt) ], p = { // Корректировка отступов w:opt.width-est*cnt, h:opt.height-est*cnt }; if(p.w > 0.01 || p.h > 0.01){ var cst = { // Отступы контейнера width:opt.width-p.w, height:opt.height-p.h, paddingLeft:R(0.5*p.w), paddingTop:R(0.5*p.h) }; cst.paddingRight=p.w-cst.paddingLeft; cst.paddingBottom=p.h-cst.paddingTop; self.css(cst); } for(var n in $$.engine){ // Поиск подходящего рендерера if($$.engine[n].check()){ $$.engine[n].render.call(self, function(col, row){ // Эта лямбда по сути запрашивает состояние элемента матрицы return gene.read.call(inst, col, row); }, cnt, est); break; } } }); }; /* Рендереры */ /* Типы кодов */ });

    Как оказалось, во многих кривых браузерах, типа всем ненавистного Internet Exploder-а и Opera не целые пикселы работают совсем уж странно, поэтому для совместимости размеры каждого элементика матрицы пришлось округлять до меньшего целого, во избежание выхода матрицы за пределы области. По этой причине матрицу пришлось отделить отступами от контейнера.

    Рендеринг

    Теперь реализуем движки-рендереры. Поскольку более приоритетным для нас будет использование Canvas, начнём с него:

    $$.engine.canvas = { check: function(){ // Проверка доступности try{ return !!window.CanvasRenderingContext2D && !!document.createElement("canvas"); }catch(e){ return false; } }, render: function(chk, cnt, est){ // Рендеринг // Для начала нам нужно получить цвета, чтобы картинка выглядела в соответствии с CSS var st = this.append("").find("span"), c = st.eq(0).css("backgroundColor"), d = st.eq(1).css("backgroundColor"), w = est.width, h = est.height; this.empty(); // А теперь инициализируем Canvas var can = this.append("").find("canvas").get(0), ctx = can.getContext("2d"); can.width = cnt*est; can.height = cnt*est; // И раскрашиваем матрицу for(var y = 0; y < cnt; y++){ for(var x = 0; x < cnt; x++){ ctx.fillStyle = chk(x, y) ? d: c; ctx.fillRect(x*est, y*est, est, est); } } } };

    Если Canvas не доступен, будем тупо генерировать матрицу HTML элементами, это медленней, но работает:

    $$.engine.html = { check: function(){ return true; }, render: function(chk, cnt, est){ var tab = ""; for(var y = 0; y < cnt; y++){ for(var x = 0; x < cnt; x++){ tab += ""; } } this.append(tab).find("span").css({ width:est, height:est }); } };

    После тестирования в IE как обычно оказалось, что это там работает вовсе не так, как задумывалось, поэтому за неимением желания разбираться напишем табличный движок:

    $$.engine.table = { check: function(){ return true; //$.browser.msie; }, render: function(chk, cnt, est){ var tab = ""; for(var y = 0; y < cnt; y++){ tab += ""; for(var x = 0; x < cnt; x++){ tab += ""; } tab += ""; } this.append("

    "+tab+"
    ").find("table").css({ width:est*cnt, height:est*cnt }).find("td").css({ width:est, height:est }); } };

    Как видите, всё получилось достаточно тривиально. Только и осталось написать таблицу стилей:

    Bar-code{ /* Контейнер */ overflow: hidden; margin: 10px; padding: 0; width: 100px; height: 100px; background: #fff; /* Фоновый цвет. Если у вас сплошная заливка, можно это свойство не задавать */ } .bar-code *{ /* Все элементы по-умолчанию */ display: inline-block; float: left; border: 0; padding: 0; margin: 0; border-collapse: collapse; } .bar-code .dark{ /* Затемнённые элементы */ background: #000; /* Можно задать любой цвет, главное чтобы он хорошо отличался от фонового, экспериментируйте */ }

    Тут я сбрасываю некоторые свойства на всякий случай, вы можете этого не делать, если итак всё отлично выглядит.

    Кодеры

    Как уже было сказано выше, мы реализуем генерацию QR-кодов , испрользуя кодировщик от Kazuhiko Arase , также до кучи и ради примера добавим генератор DataMatrix кодов, это альтернатива QR-кодам, однако менее распространённая на просторах интернета и поддерживаемая меньшим числом сканнеров. В скрипте мы будем проверять, доступен ли кодировщик и только тогда инициализировать движок.

    Кодировщик от Казухико требует обязательного указания типа кода, то есть числа от 0 до 10, которое в совокупности с уровнем коррекции ошибок составляет версию кода, однако разные типы кода способны хранить разные объёмы информации, поэтому я решил реализовать автоматический подбор типа, соответствующего данным, если тип не указан. Итак, QR-кодер будет выглядеть следующим образом:

    If(window.QRCode){ $$.defs.QR = { // Значения опций по умолчанию level: "H", // Уровень по умолчанию type: 0 // Тип по умолчанию // 1..10 // моё расширение: 0 or null - автовыбор }; var QRAutoType = function(val, errorCorrectLevel){ // Автоматический выбор подходящего типа for(var typeNumber = 1; typeNumber

    Рекомендуем почитать

    Наверх