Av-gr.ru

Двери декор
2 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Декодирование JPEG для чайников

Декодирование JPEG для чайников

Вам когда-нибудь хотелось узнать как устроен jpg-файл? Сейчас разберемся! Прогревайте ваш любимый компилятор и hex-редактор, будем декодировать это:

Jpeg file in hex editor

Специально взял рисунок поменьше. Это знакомый, но сильно пережатый favicon Гугла: Google favicon

Последующее описание упрощено, и приведенная информация не полная, но зато потом будет легко понять спецификацию.

Даже не зная, как происходит кодирование, мы уже можем кое-что извлечь из файла.

[FF D8] — маркер начала. Он всегда находится в начале всех jpg-файлов.

Следом идут байты [FF FE]. Это маркер, означающий начало секции с комментарием. Следующие 2 байта [00 04] — длина секции (включая эти 2 байта). Значит в следующих двух [3A 29] — сам комментарий. Это коды символов «:» и «)», т.е. обычного смайлика. Вы можете увидеть его в первой строке правой части hex-редактора.

Немного теории

  • Обычно изображение преобразуется из цветового пространства RGB в YCbCr.
  • Часто каналы Cb и Cr прореживают, то есть блоку пикселей присваивается усредненное значение. Например, после прореживания в 2 раза по вертикали и горизонтали, пиксели будут иметь такое соответствие:

subdiscretization

  • Затем значения каналов разбиваются на блоки 8×8 (все видели эти квадратики на слишком сжатом изображении).
  • Каждый блок подвергается дискретно-косинусному преобразованию (ДКП), являющемся разновидностью дискретного преобразования Фурье. Получим матрицу коэффициетов 8×8. Причем левый верхний коэффициент называется DC-коффициентом (он самый важный и является усредненным значением всех значений), а оставшиеся 63 — AC-коэффициентами.
  • Получившиеся коэффициенты квантуются, т.е. каждый умножается на коэффициент матрицы квантования (каждый кодировщик обычно использует свою матрицу квантования).
  • Затем они кодируются кодами Хаффмана.

Закодированные данные располагаются поочередно, небольшими частями:

blocks

Каждый блок Yij, Cbij, Crij — это матрица коэффициентов ДКП (так же 8×8), закодированная кодами Хаффмана. В файле они располагаются в таком порядке: Y00Y10Y01Y11Cb00Cr00Y20.

Чтение файла

Файл поделен на секторы, предваряемые маркерами. Маркеры имеют длину 2 байта, причем первый байт [FF]. Почти все секторы хранят свою длину в следующих 2 байта после маркера. Для удобства подсветим маркеры:

markers

Маркер [FF DB]: DQT — таблица квантования

FF DB

  • [00 43] Длина: 0x43 = 67 байт
  • [0_] Длина значений в таблице: 0 (0 — 1 байт, 1 — 2 байта)
  • [_0] Идентификатор таблицы: 0

Оставшимися 64-мя байтами нужно заполнить таблицу 8×8.

Приглядитесь, в каком порядке заполнены значения таблицы. Этот порядок называется zigzag order:

zigzag

Маркер [FF C0]: SOF0 — Baseline DCT

Этот маркер называется SOF0, и означает, что изображение закодировано базовым методом. Он очень распространен. Но в интернете не менее популярен знакомый вам progressive-метод, когда сначала загружается изображение с низким разрешением, а потом и нормальная картинка. Это позволяет понять что там изображено, не дожидаясь полной загрузки. Спецификация определяет еще несколько, как мне кажется, не очень распространенных методов.

FF C0

  • [00 11] Длина: 17 байт.
  • [08] Precision: 8 бит. В базовом методе всегда 8. Это разрядность значений каналов.
  • [00 10] Высота рисунка: 0x10 = 16
  • [00 10] Ширина рисунка: 0x10 = 16
  • [03] Количество каналов: 3. Чаще всего это Y, Cb, Cr или R, G, B
  • [01] Идентификатор: 1
  • [2_] Горизонтальное прореживание (H1): 2
  • [_2] Вертикальное прореживание (V1): 2
  • [00] Идентификатор таблицы квантования: 0
  • [02] Идентификатор: 2
  • [1_] Горизонтальное прореживание (H2): 1
  • [_1] Вертикальное прореживание (V2): 1
  • [01] Идентификатор таблицы квантования: 1
  • [03] Идентификатор: 3
  • [1_] Горизонтальное прореживание (H3): 1
  • [_1] Вертикальное прореживание (V3): 1
  • [01] Идентификатор таблицы квантования: 1

Находим Hmax=2 и Vmax=2. Канал i будет прорежен в Hmax/Hi раз по горизонтали и Vmax/Vi раз по вертикали.

Маркер [FF C4]: DHT (таблица Хаффмана)

Эта секция хранит коды и значения, полученные кодированием Хаффмана.

FF C4

  • [00 15] Длина: 21 байт
  • [0_] Класс: 0 (0 — таблица DC коэффициентов, 1 — таблица AC коэффициентов).
  • [_0] Идентификатор таблицы: 0

Следующие 16 значений:

Количество кодов означает количество кодов такой длины. Обратите внимание, что секция хранит только длины кодов, а не сами коды. Мы должны найти коды сами. Итак, у нас есть один код длины 1 и один — длины 2. Итого 2 кода, больше кодов в этой таблице нет.
С каждым кодом сопоставлено значение, в файле они перечислены следом. Значения однобайтовые, поэтому читаем 2 байта:

  • [03] — значение 1-го кода
  • [02] — значение 2-го кода
Читайте так же:
Стандартные размеры корпусной мебели

Далее в файле можно видеть еще 3 маркера [FF C4], я пропущу разбор соответствующих секций, он аналогичен вышеприведенному.

Построение дерева кодов Хаффмана

Мы должны построить бинарное дерево по таблице, которую мы получили в секции DHT. А уже по этому дереву мы узнаем каждый код. Значения добавляем в том порядке, в каком указаны в таблице. Алгоритм прост: в каком бы узле мы ни находились, всегда пытаемся добавить значение в левую ветвь. А если она занята, то в правую. А если и там нет места, то возвращаемся на уровень выше, и пробуем оттуда. Остановиться нужно на уровне равном длине кода. Левым ветвям соответствует значение 0, правым — 1.

Деревья для всех таблиц этого примера:

Huffman trees

В кружках — значения кодов, под кружками — сами коды (поясню, что мы получили их, пройдя путь от вершины до каждого узла). Именно такими кодами закодировано само содержимое рисунка.

Маркер [FF DA]: SOS (Start of Scan)

Байт [DA] в маркере означает — «ДА! Наконец-то то мы перешли к финальной секции!». Однако секция символично называется SOS.

FF DA

  • [00 0C] Длина: 12 байт.
  • [03] Количество каналов. У нас 3, по одному на Y, Cb, Cr.
  • [01] Идентификатор канала: 1 (Y)
  • [0_] Идентификатор таблицы Хаффмана для DC коэффициентов: 0
  • [_0] Идентификатор таблицы Хаффмана для AC коэффициентов: 0
  • [02] Идентификатор канала: 2 (Cb)
  • [1_] Идентификатор таблицы Хаффмана для DC коэффициентов: 1
  • [_1] Идентификатор таблицы Хаффмана для AC коэффициентов: 1
  • [03] Идентификатор канала: 3 (Cr)
  • [1_] Идентификатор таблицы Хаффмана для DC коэффициентов: 1
  • [_1] Идентификатор таблицы Хаффмана для AC коэффициентов: 1

[00], [3F], [00] — Start of spectral or predictor selection, End of spectral selection, Successive approximation bit position. Эти значения используются только для прогрессивного режима, что выходит за рамки статьи.

Отсюда и до конца (маркера [FF D9]) закодированные данные.

Закодированные данные

Последующие значения нужно рассматривать как битовый поток. Первых 33 бит будет достаточно, чтобы построить первую таблицу коэффициентов:

Code

Нахождение DC-коэффициента

1) Читаем последовательность битов (если встретим 2 байта [FF 00], то это не маркер, а просто байт [FF]). После каждого бита сдвигаемся по дереву Хаффмана (с соответствующим идентификатором) по ветви 0 или 1, в зависимости от прочитанного бита. Останавливаемся, если оказались в конечном узле.

Step 1

2) Берем значение узла. Если оно равно 0, то коэффициент равен 0, записываем в таблицу и переходим к чтению других коэффициентов. В нашем случае — 02. Это значение — длина коэффициента в битах. Т. е. читаем следующие 2 бита, это и будет коэффициент:

Step 2

3) Если первая цифра значения в двоичном представлении — 1, то оставляем как есть: DC = <значение> . Иначе преобразуем: DC = <значение>-2^<длина значения>+1 . Записываем коэффициент в таблицу в начало зигзага — левый верхний угол.

Нахождение AC-коэффициентов

1) Аналогичен п. 1, нахождения DC коэффициента. Продолжаем читать последовательность:

Step 3

2) Берем значение узла. Если оно равно 0, это означает, что оставшиеся значения матрицы нужно заполнить нулями. Дальше закодирована уже следующая матрица. В нашем случае значение узла: 0x31.

  • Первый полубайт: 0x3 — именно столько нулей мы должны добавить в матрицу. Это 3 нулевых коэффициента.
  • Второй полубайт: 0x1 — длина коэффициента в битах. Читаем следующий бит.

Step 4

  1. Аналогичен п. 3 нахождения DC-коэффициента.

Читать AC-коэффициенты нужно пока не наткнемся на нулевое значение кода, либо пока не заполнится матрица.
В нашем случае мы получим:

Step 5

Вы заметили, что значения заполнены в том же зигзагообразном порядке? Причина использования такого порядка простая — так как чем больше значения v и u, тем меньшей значимостью обладает коэффициент Svu в дискретно-косинусном преобразовании. Поэтому, при высоких степенях сжатия малозначащие коэффициенты обнуляют, тем самым уменьшая размер файла.

Читайте так же:
Оружейный ящик своими руками

Аналогично получаем еще 3 матрицы Y-канала…

Но! Закодированные DC-коэффициенты — это не сами DC-коэффициенты, а их разности между коэффициентами предыдущей таблицы (того же канала)! Нужно поправить матрицы:

  • DC для 2-ой: 2 + (-4) = -2
  • DC для 3-ой: -2 + 5 = 3
  • DC для 4-ой: 3 + (-4) = -1

Теперь порядок. Это правило действует до конца файла.

… и по матрице для Cb и Cr:

Вычисления

Квантование

Вы помните, что матрица проходит этап квантования? Элементы матрицы нужно почленно перемножить с элементами матрицы квантования. Осталось выбрать нужную. Сначала мы просканировали первый канал. Он использует матрицу квантования 0 (у нас она первая из двух). Итак, после перемножения получаем 4 матрицы Y-канала:

… и по матрице для Cb и Cr.

Обратное дискретно-косинусное преобразование

IDCT

Формула не должна доставить сложностей. Svu — наша полученная матрица коэффициентов. u — столбец, v — строка. Cx = 1/√2 для x = 0, а в остальных случаях = 1. syx — непосредственно значения каналов.

Приведу результат вычисления только первой матрицы канала Y (после обязательного округления):

Ко всем полученным значениям нужно прибавить по 128, а затем ограничить их диапазон от 0 до 255:

Например: 138 → 266 → 255, 92 → 220 → 220 и т. д.

YCbCr в RGB

4 матрицы Y, и по одной Cb и Cr, так как мы прореживали каналы и 4 пикселям Y соответствует по одному Cb и Cr. Поэтому вычислять так: YCbCrToRGB(Y[y,x], Cb[y/2, x/2], Cr[y/2, x/2]):

Вот полученные таблицы для каналов R, G, B для левого верхнего квадрата 8×8 нашего примера:

Конец

Вообще я не специалист по JPEG, поэтому вряд ли смогу ответить на все вопросы. Просто когда я писал свой декодер, мне часто приходилось сталкиваться с различными непонятными проблемами. И когда изображение выводилось некорректно, я не знал где допустил ошибку. Может неправильно проинтерпретировал биты, а может неправильно использовал ДКП. Очень не хватало пошагового примера, поэтому, надеюсь, эта статья поможет при написании декодера. Думаю, она покрывает описание базового метода, но все-равно нельзя обойтись только ей. Предлагаю вам ссылки, которые помогли мне:

Порядок прилагательных в английском языке

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

  • a young girl – молодая девушка;
  • a black table – черный стол;
  • an interesting book – интересная книга.

А что делать, если прилагательных, относящихся к слову, два, три или больше? Каков будет порядок прилагательных в английском языке, если мы сталкиваемся с такой ситуацией? Ответ на этот вопрос вы найдете в нашей статье.

Какие бывают прилагательные

Безусловно, английский – язык исключений и всевозможных поправок. Но он имеет определенный алгоритм, согласно которому все английские прилагательные занимают свое место перед существительным.

Все прилагательные можно разделить на две большие группы: субъективные (opinion adjectives) и объективные (fact adjectives). Первые отвечают за то, как мы воспринимаем тот или иной предмет (лицо или явление) и какую оценку ему даем. Вторая группа предоставляет реально существующую информацию о чем-либо, то есть то, с чем не поспоришь. Это может быть размер, цвет, возраст и т. д. Сначала мы ставим субъективное прилагательное, а затем объективное:

  • an unusual gold ring – необычное (субъективное мнение) золотое (реальная информация) кольцо;
  • a nice old lady – приятная (субъективное мнение) пожилая (реальная информация) дама;
  • a lovely sunny day – чудесный (субъективное мнение) солнечный (реальная информация) день;
  • a delicious hot soup – вкусный (субъективное мнение) горячий (реальная информация) суп;
  • an interesting historical movie – интересный (субъективное мнение) исторический (реальная информация) фильм.

Порядок прилагательных в английском предложении

Усложняем ситуацию. До этого мы говорили лишь о двух прилагательных, стоящих перед именем существительным. Теперь разрабатываем план действий в ситуации с тремя и более прилагательными. Порядок объективных прилагательных в английском языке при наличии двух и более слов организован следующим образом:

  1. Общее качество (general quality), цена (price): new (новый), broken (поломанный), expensive (дорогой), cheap (дешевый).
  2. Размер (size): big (большой), small (маленький), tall (высокий), short (короткий, невысокий).
  3. Физические характеристики (physical quality): hard (твердый), fragile (хрупкий) rough (неровный), smooth (гладкий).
  4. Форма (shape): square (квадратный), round (круглый), triangular (треугольный), almond-shaped (миндалевидный).
  5. Возраст (age): young (молодой), old (старый), mature (зрелый), middle-aged (средних лет).
  6. Цвет (colour): red (красный), purple (фиолетовый), olive-green (оливковый), indigo (темно-синий).
  7. Происхождение (origin): Italian (итальянский), Mexican (мексиканский), European (европейский), Far Eastern (дальневосточный).
  8. Вещество (substance), материал (material): wooden (деревянный), bronze (бронзовый), tin (оловянный), plastic (пластмассовый).
  9. Предназначение, цель (purpose): work (рабочий), cleaning (чистящий), cooking (для готовки), sleeping (для сна).
Читайте так же:
Чем покрасить табуретку

* Пункты 4 и 5 могут меняться местами.

Теперь давайте посмотрим на примерах, как выстраиваются прилагательные в предложении. В примерах у каждого прилагательного есть цифра, совпадающая с его порядковым номером в списке. Цифрой 0 обозначены субъективные прилагательные.

Как выбрать правильный размер обуви Dr. Martens?

Как определить размер Dr. Martens

Заказывать обувь онлайн проще, быстрее и удобнее, чем часами курсировать по рынкам и магазинам, но покупка в интернете имеет свои нюансы. Нужно знать, как отличить подделку , заранее выбирать модель, цвет и, самое главное, размер. И все это без возможности примерки!

Конечно, всегда можно вернуть товар в онлайн-магазин и обменять на более подходящий, но это дело не быстрое. Лучше просто определить свой размер ноги заранее, чтобы избежать дальнейших проблем.

Как определить свой размер ноги?

Совсем не сложно! Листок А4, карандаш и линейка — вот и весь необходимый инвентарь. Даже меньше, чем нужно ребенку для урока черчения в младшей школе.

В идеале необходимо измерить обе ноги. Параметры, скорее всего, будут слегка отличаться, так что за «норму» берите ту ногу, которая больше.

Всю эту процедуру лучше всего затевать вечером: нога к концу дня слегка отекает и становится шире, чем была утром. Пугаться тут нечего, это естественный процесс, но его стоит учитывать при замерах. Также лучше надеть носки или колготы, которые вы собираетесь носить под мартинсы. Вы же не станете обувать ботинки на босую ногу, верно?

Пошаговая инструкция как определить свой размер ноги:

  1. Положите на пол листок бумаги и поставьте сверху свою ногу. Вам нужно будет по контуру обвести стопу, так что лучше всего класть лист на твердую и ровную поверхность. Никаких ковров и мягких дорожек — только голый пол, только хардкор!
  2. Аккуратно обведите ногу карандашом. Чтобы рисунок вышел максимально точным, держите карандаш перпендикулярно поверхности, то есть максимально прямо и ровно.
  3. При помощи линейки начертите ровную линию по самой крайней точке на каждой из сторон рисунка. Получится контур ноги в узком прямоугольнике.
  4. Теперь возьмите получившийся у вас шедевр современного кубизма и проведите прямую ровную линию от кончика большого пальца до пятки. Измерьте ее. Запишите результат — это длина вашей ноги.

5. Затем проведите прямую ровную линию от самой крайней точки сбоку (она будет находиться чуть ниже основания пальцев) до противоположной стороны рисунка. Так вы узнаете ширину вашей ноги.

6. Наконец, воспользуйтесь таблицей размеров, чтобы определить свой, исходя из длины и ширины ступни.

Таблица размеров обуви Dr. Martens

После того, как вы узнали длину вашей стопы, необходимо сверить её с размерной сеткой. Dr. Martens — британский бренд, поэтому производитель использует единицу измерения UK как основную. По нашим наблюдениям, размер мартинсов часто совпадает с размером, который вы носите в украинской или европейской обуви.

Размер может варьироваться, в зависимости от модели. По ширине продукция Dr. Martens рассчитана на среднюю стопу. (см. ниже)

Иногда мартинсы жмут в подъеме — такое бывает. Достаточно два-три раза надеть их на плотный носок с растяжителем для кожи и погулять по дому или же сделать короткую прогулку по улице.

Читайте так же:
Сурская мебель валерия модули размеры

Вероятнее всего, со временем ваши ботинки разносятся в подъеме и по бокам. Если же мартинсы жмут по длине — их лучше вернуть. Обувь не должна причинять вам боль и травмы, иначе это может испортить ваше впечатление о продукции бренда и закончиться плачевно для ваших ступней.

Поначалу обязательно носите ваши новые мартинсы на плотный носок — это избавит вас от неприятных мозолей. В нашей статье есть больше информации о том, как правильно разнашивать мартинсы .

Модели Dr. Martens и их размеры

Классические унисекс модели Dr. Martens 1460 , 1461 и 2976 (челси) зачастую большемерят, поэтому, если вы носите размер 38.5, вам, скорее всего, подойдет UK 5/ EU 38 размер ботинок

Броги и лоферы имеют низкий подъем и немного уже, чем классические туфли.

В моделях 1460 Patent , Pascal , Serena и Leonore полномерные, поэтому лучше заказывать тот размер мартинсов, который вы носите в украинской обуви.

Почему так важно узнать точный размер ноги?

Самая очевидная причина — чтобы обувь нормально сидела на ноге, не спадала и не жала. Но на самом деле такой вариант наименее страшен: вы сразу понимаете, что ботинки вам не подходят, отсылаете их назад в магазин и меняете на другой размер. А вот если мартинсы большемерят, но в остальном вроде как сидят нормально, — это гораздо хуже.

Такую обувь вы, скорее всего, не будете никуда возвращать, а просто начнете носить. И получите в итоге не только дискомфорт, но даже некоторые специфические заболевания.

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

Как мы можем помочь?

Мы рекомендуем заранее измерить свой размер ноги, чтобы избежать потери времени, ненужных неудобств, травм и всяческих разочарований. В нашем интернет-магазине действует возврат-обмен на большинство моделей Dr. Martens, поэтому вы можете не переживать, если обувь вдруг окажется вам не впору.

Если у вас возникли какие-либо вопросы касательно размеров обуви или по каким-то другим темам, вы всегда можете обратиться к консультанту . Это поможет вам быстро и досконально разобраться в любых сложностях, связанных с выбором ботинок Dr. Martens на сайте.

Поделитесь вашим опытом с мартинсами — это поможет другим более точно определиться с выбором размера. Будем рады увидеть ваши комментарии внизу

Пиксельная манипуляция с холстом

До сих пор мы не смотрели на фактические пиксели нашего объекта canvas (далее «холст»). С объектом ImageData вы можете напрямую читать и писать массив данных для управления пиксельными данными. Мы также рассмотрим, как можно сгладить сглаживание изображения (сглаживание) и как сохранить изображения с вашего холста.

Объект ImageData

Объект ImageData представляет базовые пиксельные данные области объекта холста. Он содержит следующие атрибуты только для чтения:

width Ширина изображения в пикселях. height Высота изображения в пикселях. data A Uint8ClampedArray представляет собой одномерный массив, содержащий данные в порядке RGBA, с целыми значениями от 0 до 255 (в комплекте).

Свойство data возвращает Uint8ClampedArray , к которому можно получить доступ, чтобы посмотреть на необработанные пиксельные данные; каждый пиксель представлен четырьмя однобайтовыми значениями (красный, зелёный, синий и альфа в этом порядке, то есть формат «RGBA»). Каждый компонент цвета представлен целым числом от 0 до 255. Каждому компоненту присваивается последовательный индекс внутри массива, причём красный компонент верхнего левого пикселя находится в индексе 0 внутри массива. Затем пиксели идут слева направо, затем вниз, по всему массиву.

Uint8ClampedArray содержит высоту × ширину × 4 байта данных, значения индекса варьируются от 0 до (высота × ширина × 4) -1.

Например, чтобы прочитать значение синего компонента из пикселя в столбце 200, строка 50 на изображении, вы должны сделать следующее:

Вы можете получить доступ к размеру массива пикселей в байтах, прочитав атрибут Uint8ClampedArray.length :

Создание объекта ImageData

Чтобы создать новый пустой объект ImageData , вы должны использовать метод createImageData () (en-US) . Существуют две версии метода createImageData() :

Читайте так же:
Hellen farben фасады

Это создаёт новый объект ImageData с указанными параметрами. Все пиксели заданы прозрачным черным.

Вы также можете создать новый объект ImageData ImageData с теми же размерами, что и объект, заданный anotherImageData . Все пиксели нового объекта установлены на прозрачный чёрный. Это не копирует данные изображения!

Получение пиксельных данных для контекста

Чтобы получить объект ImageData , содержащий копию пиксельных данных для контекста холста, вы можете использовать метод getImageData() :

Этот метод возвращает объект ImageData , представляющий пиксельные данные для области холста, углы которого представлены точками ( left , top ), ( left+width , top ), ( left , top+height ) и ( left+width , top+height ). Координаты задаются в единицах пространства координат холста.

Примечание: Любые пиксели за пределами холста возвращаются как прозрачный чёрный цвет в результирующий объект ImageData .

Этот метод также показан в статье Manipulating video using canvas.

Выбор цвета

В этом примере мы используем метод getImageData() для отображения цвета под курсором мыши. Для этого нам нужна текущая позиция мыши с layerX и layerY , затем мы просматриваем пиксельные данные в этой позиции в массиве пикселей, который предоставляет нам getImageData() . Наконец, мы используем данные массива для установки цвета фона и текста <div> для отображения цвета.

Отображение пиксельных данных в контекст

Вы можете использовать метод putImageData() для рисования пиксельных данных в контексте:

Параметры dx и dy указывают координаты устройства в контексте, в котором будет отображаться верхний левый угол пиксельных данных, которые вы хотите нарисовать.

Например, чтобы нарисовать все изображение, представленное myImageData , в верхнем левом углу контекста, вы можете просто сделать следующее:

Оттенки серого цвета и инвертирование цветов

В этом примере мы перебираем все пиксели для изменения их значений, а затем помещаем модифицированный массив пикселей обратно в canvas с помощью putImageData(). Функция инвертирования просто вычитает каждый цвет из максимального значения 255. Функция оттенков серого просто использует среднее значение красного, зелёного и синего. Вы также можете использовать средневзвешенное значение, заданное формулой x = 0.299r + 0.587g + 0.114b , например. Для дополнительной информации см. Grayscale в Википедии.

Масштабирование и сглаживание

С помощью метода drawImage () , второго холста и свойства imageSmoothingEnabled (en-US) мы способны увеличить изображение и посмотреть его более детально.

Мы получаем положение мыши и обрезаем изображение на 5 пикселей левее и выше и на 5 пикселей правее и ниже положения мыши. Затем мы копируем его на другой холст и изменяем размер изображения до размера, который мы хотим. При масштабировании мы изменяем холст с исходного размера 10×10 пикселей до 200×200.

Поскольку по умолчанию включено сглаживание, мы можем захотеть отключить сглаживание, чтобы увидеть чёткие пиксели. Вы можете переключить флажок, чтобы увидеть эффект свойства imageSmoothingEnabled (которому нужны префиксы для разных браузеров).

Zoom example

Сохранение изображений

HTMLCanvasElement предоставляет метод toDataURL() , который полезен при сохранении изображений. Он возвращает data URI, содержащий представление изображения в формате, заданном параметром type (по умолчанию используется в PNG ). Возвращаемое изображение имеет разрешение 96 точек на дюйм.

Примечание: Имейте в виду, что если холст содержит пиксели, полученные из другого origin без использования CORS, холст будет испорчен, и его содержимое больше не будет считываться и сохраняться. Смотрите Безопасность и испорченные холсты в Allowing cross-origin use of images and canvas canvas.toDataURL(‘image/png’) Настройки по умолчанию. Создаёт изображение в формате PNG. canvas.toDataURL(‘image/jpeg’, quality) Создаёт изображение в формате JPG. Дополнительно вы можете задать параметр «качество» (quality) в диапазоне от 0 до 1, причём единица задаёт лучшее качество и 0 — почти не распознаваемый, но небольшой по размеру файл.

После того как вы создали URI данные из своего холста, вы можете использовать его как источник любого <image> или поместить его в гиперссылку с download attribute, чтобы сохранить его на диске, например.

голоса
Рейтинг статьи
Ссылка на основную публикацию
Adblock
detector