Данный двоичный код 8-ми цветного изображения монитора размером 10x10 пикселей показан на рисунке

Обновлено: 24.11.2024

Это руководство взято из книги Дэниела Шиффмана Learning Processing, опубликованной Морганом Кауфманном, © Elsevier Inc., 2008. Все права защищены. Если вы заметили какие-либо ошибки или у вас есть комментарии, сообщите нам об этом.

Цифровое изображение — это не что иное, как данные — числа, обозначающие вариации красного, зеленого и синего цветов в определенном месте сетки пикселей. Большую часть времени мы видим эти пиксели как миниатюрные прямоугольники, склеенные вместе на экране компьютера. Однако, приложив немного творческого мышления и немного манипулируя пикселями с помощью кода, мы можем отображать эту информацию множеством способов. Это руководство посвящено переходу от простого рисования фигур в Обработке и использованию изображений (и их пикселей) в качестве строительных блоков Обработки графики.

Начало работы с изображениями.

Надеюсь, вам нравится идея типов данных. Вероятно, вы часто их указываете — переменная с плавающей запятой «скорость», целое число «х» и т. д. Все это примитивные типы данных, биты, хранящиеся в памяти компьютера и готовые для нашего использования. Хотя, возможно, это немного сложнее, мы надеемся, что вы также используете объекты, сложные типы данных, которые хранят несколько фрагментов данных (наряду с функциональностью) — например, класс «Ball» может включать переменные с плавающей запятой для местоположения, размера и скорости. как методы для перемещения, отображения себя и т. д.

В дополнение к определяемым пользователем объектам (например, Ball) в Processing есть множество удобных классов, готовых к работе без написания кода. В этом руководстве мы рассмотрим PImage, класс для загрузки и отображения изображения, а также просмотра его пикселей.

Использование экземпляра объекта PImage ничем не отличается от использования определяемого пользователем класса. Сначала объявляется переменная типа PImage с именем img. Во-вторых, новый экземпляр объекта PImage создается с помощью метода loadImage(). loadImage() принимает один аргумент, строку, указывающую имя файла, и загружает этот файл в память. loadImage() ищет файлы изображений, хранящиеся в папке «data» скетча Processing.

Папка данных: как туда попасть?

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

Эскиз → Добавить файл. . .

Эскиз → Показать папку эскиза

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

Обработка принимает следующие форматы файлов для изображений: GIF, JPG, TGA, PNG.

В приведенном выше примере может показаться немного странным, что мы никогда не вызывали «конструктор» для создания экземпляра объекта PImage, говоря new PImage() . В конце концов, в большинстве примеров, связанных с объектами, конструктор необходим для создания экземпляра объекта.

Фактически функция loadImage() выполняет работу конструктора, возвращая совершенно новый экземпляр объекта PImage, сгенерированный из указанного имени файла. Мы можем думать об этом как о конструкторе PImage для загрузки изображений из файла. Для создания пустого изображения используется функция createImage().

Мы также должны отметить, что процесс загрузки образа с жесткого диска в память является медленным, и мы должны убедиться, что наша программа делает это только один раз, в setup() . Загрузка изображений в draw() может привести к снижению производительности, а также к ошибкам «Недостаточно памяти».

После загрузки изображения оно отображается с помощью функции image(). Функция image() должна включать 3 аргумента — отображаемое изображение, координаты x и координаты y. При желании можно добавить два аргумента для изменения размера изображения до определенной ширины и высоты.

Ваш самый первый фильтр для обработки изображений

При отображении изображения вы можете изменить его внешний вид. Возможно, вы хотели бы, чтобы изображение выглядело более темным, прозрачным, голубоватым и т. д. Этот тип простой фильтрации изображения достигается с помощью функции tint() Processing. tint() по существу эквивалент изображения fill() формы, устанавливая цвет и альфа-прозрачность для отображения изображения на экране. Тем не менее, изображение обычно не бывает одноцветным. Аргументы для tint() просто указывают, сколько данного цвета использовать для каждого пикселя этого изображения, а также насколько прозрачными должны быть эти пиксели.

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

Если tint() получает один аргумент, затрагивается только яркость изображения.

Второй аргумент изменит альфа-прозрачность изображения.

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

Наконец, добавление четвертого аргумента к методу манипулирует альфа-каналом (так же, как и с 2). Между прочим, диапазон значений для tint() можно указать с помощью colorMode().

Пиксели, пиксели и еще раз пиксели

Если вы только начали использовать Processing, вы, возможно, ошибочно полагали, что единственным предлагаемым способом рисования на экране является вызов функции. «Нарисуйте линию между этими точками», или «Залейте эллипс красным», или «загрузите это изображение в формате JPG и поместите его на экран здесь». Но где-то каким-то образом кто-то должен был написать код, который переводит эти вызовы функций в настройку отдельных пикселей на экране для отражения запрошенной формы. Линия появляется не потому, что мы говорим line(), она появляется, потому что мы окрашиваем все пиксели вдоль линейного пути между двумя точками. К счастью, нам не нужно ежедневно управлять этой низкоуровневой настройкой пикселей. Мы должны поблагодарить разработчиков Processing (и Java) за множество функций рисования, которые заботятся об этом бизнесе.

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

Мы знакомы с идеей, что каждый пиксель на экране имеет положение X и Y в двухмерном окне. Однако массив пикселей имеет только одно измерение, храня значения цвета в линейной последовательности.

Возьмите следующий простой пример. Эта программа устанавливает для каждого пикселя в окне случайное значение оттенков серого. Массив пикселей ничем не отличается от любого другого массива, с той лишь разницей, что его не нужно объявлять, так как это встроенная переменная Processing.

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

    Эта функция вызывается перед тем, как вы получите доступ к массиву пикселей, говоря: «Загрузите пиксели, я хотел бы поговорить с ними!» Эта функция вызывается после того, как вы закончите работу с массивом пикселей и скажете: «Давай, обнови пиксели, я готов!»

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

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

  1. Допустим окно или изображение с заданными значениями WIDTH и HEIGHT.
  2. Тогда мы знаем, что общее количество элементов массива пикселей равно WIDTH * HEIGHT.
  3. Для любой заданной точки X, Y в окне расположение в нашем одномерном массиве пикселей: РАСПОЛОЖЕНИЕ = X + Y * ШИРИНА.

Это может напомнить вам наш учебник по двумерным массивам. На самом деле нам нужно будет использовать ту же технику вложенных циклов for. Разница в том, что, хотя мы хотим использовать циклы for, чтобы думать о пикселях в двух измерениях, когда мы переходим к фактическому доступу к пикселям, они находятся в одномерном массиве, и мы должны применить формулу из приведенной выше иллюстрации.

Давайте посмотрим, как это делается.

Введение в обработку изображений

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

  1. Загрузить файл изображения в объект PImage
  2. Для каждого пикселя в PImage извлеките цвет пикселя и установите этот цвет для отображаемого пикселя.

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

Доступ к этим полям позволяет нам просмотреть все пиксели изображения и отобразить их на экране.

Теперь мы, безусловно, могли бы придумать упрощения, чтобы просто отображать изображение (например, вложенный цикл не требуется, не говоря уже о том, что использование функции image() позволит нам полностью пропустить всю эту работу с пикселями .) Однако в примере 15-7 представлена ​​базовая структура для получения значений красного, зеленого и синего для каждого пикселя на основе его пространственной ориентации (местоположения XY); в конечном итоге это позволит нам разработать более совершенные алгоритмы обработки изображений.

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

Наш второй фильтр изображения, создающий собственный «оттенок»

Всего несколько абзацев назад мы наслаждались расслабляющим сеансом кодирования, раскрашивая изображения и добавляя альфа-прозрачность с помощью удобного метода tint(). Для базовой фильтрации этот метод сработал. Однако метод «пиксель за пикселем» позволит нам разработать собственные алгоритмы для математического изменения цветов изображения. Учитывайте яркость — более яркие цвета имеют более высокие значения красного, зеленого и синего компонентов. Отсюда естественно следует, что мы можем изменять яркость изображения, увеличивая или уменьшая цветовые компоненты каждого пикселя. В следующем примере мы динамически увеличиваем или уменьшаем эти значения в зависимости от горизонтального положения мыши. (Обратите внимание, следующие два примера включают только сам цикл обработки изображения, остальная часть кода предполагается.)

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

Запись в пиксели другого объекта PImage

Все наши примеры обработки изображений считывают каждый пиксель исходного изображения и записывают новый пиксель непосредственно в окно обработки. Однако часто удобнее записывать новые пиксели в целевое изображение (которое затем отображается с помощью функции image()). Мы продемонстрируем эту технику, рассмотрев другую простую операцию с пикселями: порог.

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

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

Но если все, что вам нужно сделать, это установить порог, вот как это сделать:

Уровень II: обработка группы пикселей

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

Начнем с создания нового пикселя из двух пикселей исходного изображения — пикселя и его соседа слева.

Если мы знаем, что пиксель расположен в точке (x,y):

Тогда его левый сосед находится в точке (x-1,y):

Затем мы могли бы создать новый цвет из разницы между пикселем и его соседом слева.

Вот полный алгоритм:

Этот пример представляет собой простой алгоритм обнаружения горизонтальных границ. Когда пиксели сильно отличаются от своих соседей, они, скорее всего, являются «краевыми» пикселями. Например, представьте изображение белого листа бумаги на черной столешнице. Края этой бумаги — это места, где цвета наиболее сильно различаются, где белый встречается с черным.

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

Эти алгоритмы обработки изображений часто называют "пространственной сверткой". Процесс использует средневзвешенное значение входного пикселя и его соседей для вычисления выходного пикселя. Другими словами, этот новый пиксель является функцией площади пикселей. Можно использовать соседние области разных размеров, например, матрицу 3x3, 5x5 и т. д.

Различные комбинации весов для каждого пикселя приводят к различным эффектам. Например, мы «увеличиваем резкость» изображения, вычитая значения соседних пикселей и увеличивая пиксель центральной точки. Размытие достигается путем получения среднего значения всех соседних пикселей. (Обратите внимание, что значения в матрице свертки в сумме дают 1).

Ниже приведен пример, в котором выполняется свертка с использованием двумерного массива (см. главу 13, стр. XX для обзора двумерных массивов) для хранения весов пикселей матрицы 3x3. Этот пример, вероятно, является наиболее продвинутым примером, с которым мы столкнулись в этой книге, поскольку он включает в себя очень много элементов (вложенные циклы, 2D-массивы, пиксели PImage и т. д.)

Визуализация изображения

Вы можете подумать: "Боже, это все очень интересно, но если серьезно, когда я хочу размыть изображение или изменить его яркость, мне действительно нужно писать код? Я имею в виду, нельзя ли мне использовать Photoshop? " На самом деле то, чего мы здесь добились, — это просто вводное понимание того, чем занимаются высококвалифицированные программисты в Adobe. Однако сила Processing заключается в потенциале интерактивных графических приложений в реальном времени. Нам не нужно жить в рамках обработки «точек пикселей» и «групп пикселей».

Ниже приведены два примера алгоритмов обработки рисунков. Вместо того, чтобы раскрашивать фигуры случайным образом или жестко запрограммированными значениями, как это было раньше, мы выбираем цвета из пикселей внутри объекта PImage. Само изображение никогда не отображается; скорее, он служит базой данных информации, которую мы можем использовать для множества творческих целей.

В этом первом примере для каждого цикла через функцию draw() мы заполняем один эллипс в случайном месте на экране цветом, взятым из соответствующего места на исходном изображении. В результате получается базовый эффект «пуантилизма»:

В следующем примере мы берем данные из двухмерного изображения и с помощью методов трехмерного преобразования, описанных в главе 14, визуализируем прямоугольник для каждого пикселя в трехмерном пространстве. Расположение z определяется яркостью цвета. Более яркие цвета кажутся ближе к зрителю, а темные — дальше.

Изображения могут быть представлены несколькими способами. Наиболее распространенным является сетка из маленьких квадратов, называемых пикселями. В очень простом изображении, которое было только черно-белым, мы могли представить каждый пиксель как представленный 0 (черный) или 1 (белый). Таким образом, это изображение:

Можно хранить как двоичную строку из 36 бит: 111111101101111111101101100001111111. Чтобы успешно нарисовать изображение из этого шаблона, нам нужно знать, как интерпретировать эти серии двоичных цифр как 6 строк по 6 пикселей (а не 4 строки по 6 пикселей). 9 пикселей), поэтому форматы файлов реальных изображений часто содержат дополнительную информацию, например размер изображения.

На изображениях часто требуется передать оттенки серого или цвета. Для этого каждому пикселю может быть присвоено более одного бита. Если каждому пикселю присвоить значение, состоящее из 2 бит, мы можем иметь 4 цвета:

Используя эту схему, мы могли бы сделать такой заштрихованный круг:

Для представления этого изображения требуется 72 бита — сетка пикселей 6x6, для каждого из которых требуется 2 бита. Еще раз, чтобы нарисовать изображение из битов, нам нужно знать размеры изображения; но теперь нам также нужно указать количество битов, используемых для каждого пикселя. Эти 72 бита могут представлять изображение 3x6, где каждый пиксель представлен 4 битами (4 бита мы можем представить \(2^4 = 16\) разных оттенков серого).

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

32 бита могут представлять изображение 4x8 из 1-битных пикселей, или изображение 4x4 из 2-битных пикселей, или последовательность из 4 букв ASCII, или действительно большое двоичное число, или что-то еще.

Что насчет цветов? Помните, биты имеют только то значение, которое мы им приписываем. Мы могли бы интерпретировать 2 бита на пиксель так:

И в итоге получится вот это изображение:

Если нам нужно более 4 цветов, нам просто нужно больше 2 бит. С 8 битами на пиксель мы можем представить \(2^8 = 256\) разных цветов или оттенков серого. Этого достаточно для черно-белой фотографии, но не позволяет получить тонкие оттенки цвета на фотографии. Для полноцветных изображений обычно используется 24 бита на пиксель, что позволяет использовать \(2^ = 16 777 216\) разных цветов.

Конечно, реальные изображения используют гораздо большее количество пикселей, чем мы видели здесь. Например, 12-мегапиксельная камера снимает изображения размером около 4000x3000 пикселей. Если каждый из этих пикселей хранить как 24-битное значение, это изображение будет состоять из 4000 x 3000 x 24 = 288 000 000 битов информации! Это 36 000 000 байт или примерно 34,3 МБ. Однако, если вы посмотрите на файл изображения, созданный этой камерой, вы обнаружите, что он намного меньше 34 МБ, даже несмотря на то, что файл хранит дополнительную информацию помимо содержимого каждого пикселя (размеры изображения, количество битов и т. д.). на пиксель и т. д.). Это связано с тем, что изображение было сжато. Наиболее распространенные форматы изображений (gif, jpeg, png) включают некоторую форму сжатия для уменьшения места, необходимого для хранения их информации… тема, о которой мы узнаем подробнее позже.

Самопроверка

В-1. Сколько бит потребуется для изображения 10 x 20 с 8 различными возможными цветами на пиксель? (Подсказка: сколько бит требуется для представления 8 разных цветов)

Мы рекомендуем вам прочитать главу 8 (стр. 340–350) и главу 5 вашей книги Head First HTML and CSS.

Основываясь на идее представления, мы обсудим, как изображения представлены в цифровой форме. Мы будем работать над этим, сначала начав с того, как представлен цвет (который основан на физиологии человеческого глаза), а затем рассматривая изображения как прямоугольные расположения пятен чистого цвета. Наконец, мы рассчитаем размер файла изображения и обсудим один из способов сжатия файла, чтобы он был меньше и, следовательно, загружался быстрее. Это сжатие фактически является другим представлением информации.

Стандартные цвета

В настоящее время современные браузеры поддерживают 140 названий цветов. Это означает, что мы можем использовать имена цветов, такие как черный, бирюзовый или шоколадный, в качестве значений свойств CSS, за исключением значения цвета, такого как цвет, фоновый цвет и т. д. Много лет назад браузеры могли поддерживать только 17 названий цветов, известные как стандартные цвета: бирюзовый, черный, синий, фуксия, серый, зеленый, салатовый, темно-бордовый, темно-синий, оливковый, оранжевый, фиолетовый, красный, серебристый, бирюзовый, белый и желтый. Однако позже этот список был расширен еще на 123 цвета. W3Schools поддерживает полный список из 140 признанных названий цветов. Хотя вы можете добиться многого, используя только эти именованные цвета, очень часто вам нужно что-то более конкретное из цветового спектра. Оказывается, мы можем использовать числовые коды для обозначения цветов, потому что внутри компьютера цвета представлены числами. Как? Для этого нам нужно понимать аддитивные цвета и цветовое зрение.

Аддитивные (RGB) цвета и цветовое зрение

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

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

На компьютерах компоненты цвета RGB стандартно определяются по шкале от 0 до 255, что составляет 8 бит или 1 байт.

Поиграйте со страницей ползунка "Цвет", чтобы почувствовать это.

Пример аддитивного смешивания.

<УЛ>
  • Василек = 100 149 237
  • Зеленый лес = 34 139 34
  • Золото = 255 215 0
  • ДоджерСиний = 30 144 255
  • Сиена = 160 82 45
  • Горячий розовый = 255 105 180
  • Мы можем использовать эти знания о цветах, представленных как смесь красного, синего и зеленого, при указании значений цвета в CSS. Это можно сделать тремя способами:

    Шестнадцатеричный

    Люди используют десятичную систему счисления (основание 10), компьютеры используют двоичную систему (основание 2), но программисты часто используют для удобства шестнадцатеричное число (основание 16).

    Двоичные числа очень быстро удлиняются. Нелегко запомнить 24 двоичных разряда, но легче запомнить 6 шестнадцатеричных разрядов. Каждая шестнадцатеричная цифра представляет ровно четыре двоичных цифры (бита). (Это потому, что 2 4 = 16.)

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

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

    Шестнадцатеричный формат. Проделайте то же самое с наборами из 16, и вы изобретете двузначные числа с основанием 16. Например, если у вас есть тридцать пять палочек , их можно разделить на две группы по шестнадцать и три оставшихся числа. закончено, поэтому шестнадцатеричная запись равна 23. Осторожно! Это число не десятичное число двадцать три! Это по-прежнему тридцать пять палочек, но мы записываем их в шестнадцатеричном формате как 23.

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

    И десятичная, и шестнадцатеричная система счисления основаны на разрядном значении. Мы говорим, что 2316 означает 3510, потому что это "2" в разряде шестнадцати и "3" в единицах< /em>, точно так же, как 3510 имеет "3" в разряде десятков и "5" в разряде единиц.< /p>

    Возьмем другой пример. Предположим, у нас есть 2610 палочек. Осталась одна группа из 16 и 10 человек. Как записать это число в шестнадцатеричном виде? Это 11016? То есть "1" в разряде шестнадцати, за которым следует "10" в разряде единиц? Нет; это сбило бы с толку, поскольку выглядело бы как трехзначное число. Нам нужен символ, который означает десять. Мы не можем использовать «10», так как это не отдельный символ. Вместо этого мы используем «А»; то есть A16=1010. Точно так же «B» означает 11, «C» означает 12, «D» означает 13, «E» означает 14, а «F» означает 15. Нам больше не нужны символы, потому что мы не можем иметь 16 вещей. осталось, так как это составит еще одну группу из 16. В следующей таблице приведены эти соответствия и то, что мы сделали до сих пор.

    Чтобы преобразовать большое десятичное число в шестнадцатеричное, просто разделите его. Например, 23010, разделенное на 16, равно 1410 с остатком 610. Таким образом, шестнадцатеричное число равно E616. Чтобы преобразовать шестнадцатеричное число в десятичное, просто умножьте: E616=E*16 + 6 = 14*16 + 6 = 230 .

    Упражнение 1

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

    Вы можете проверить свою работу с помощью следующей формы:

    Преобразование шестнадцатеричной системы счисления в двоичную или из нее

    Теперь, когда мы знаем как шестнадцатеричный, так и двоичный формат, вы можете преобразовать двоичный код в шестнадцатеричный (и наоборот). Однако вы, вероятно, сделаете это, преобразовав двоичное число в десятичное, а затем десятичное число в шестнадцатеричное. Есть способ получше, почти без арифметики (точнее, вся арифметика с однозначными числами, которые можно складывать в уме). Действительно, этот метод является причиной, по которой программисты любят использовать шестнадцатеричный формат. (Ну, это и удовольствие от написания слов, таких как ACE и DEADBEEF, с шестнадцатеричными цифрами.)

    Пример 1

    Начнем с примера. Предположим, вам нужно преобразовать следующее из двоичного в шестнадцатеричное:

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

    Теперь мы просто конвертируем каждый фрагмент напрямую в шестнадцатеричный формат. Первый фрагмент, 0101, это просто номер 5. Второй фрагмент, 0100, это просто номер 4. Они уже в шестнадцатеричном формате, поэтому мы закончили:

    (Попробуйте сделать это с помощью десятичного числа, чтобы проверить. Десятичное значение, соответствующее обоим этим, равно 80+4=84.)

    Пример 2

    Давайте сделаем еще один, на этот раз с немного большими значениями:

    Снова возьмите биты порциями по четыре бита:

    Теперь мы просто конвертируем каждый фрагмент напрямую в шестнадцатеричный формат. Первый фрагмент, 1010, равен 8+2 или 1010, что является цифрой A в шестнадцатеричном формате. Второй блок, 1100, равен 8+4 или 1210, что является цифрой C в шестнадцатеричном формате. Итак, мы закончили:

    (Опять же, проверьте нашу работу, выполнив ее через десятичную дробь. Десятичное значение, соответствующее обоим этим, равно 160+12=172.)

    Пояснение

    Обратите внимание, что единственная арифметическая операция, которую нам нужно выполнить, — это преобразовать каждую порцию из четырех битов в эквивалентную шестнадцатеричную цифру.Используемая арифметика в уме ограничена: мы знаем, что (1) мы складываем однозначные числа, (2) не более четырех из них и (3) сумма всегда будет меньше 16.

    Посмотрите продолжение выступления профессора Курмаса из Государственного университета Гранд-Вэлли о двоичных и шестнадцатеричных числах. Это версия, которую он отредактировал для нас. Вы смотрели первые 5 минут в последний раз; смотреть остальные на сегодня.

    Вот видео, на котором Том Лерер поет New Math . Это около 4 минут; вам понравится.

    Цвета в шестнадцатеричном формате

    Вот более полный список названий цветов. --> Упражнение 2

    Используя созданную ранее веб-страницу (или этот пример веб-страницы), поэкспериментируйте с числовым определением цвета. Используйте тег SPAN, чтобы раскрасить текст. Если вы не можете придумать какой цвет попробовать, попробуйте Шоколадный. Синтаксис:

    Вот оно! Требуется некоторая практика, чтобы научиться вычислять шестнадцатеричные числа, но ничего такого, чего вы не делали раньше.-->

    Упражнение 2

    Представление изображения

    Теперь, когда мы знаем, как представлять цвет, мы можем представлять изображения. Вы можете думать об изображении как о прямоугольной двумерной сетке пятен чистого цвета, каждое из которых представлено как RRGGBB. Пятно чистого цвета называется пикселем, сокращением от элемента изображения, атомом изображения. Пиксели лучше видны, если увеличить изображение несколько раз; вот несколько примеров. Нажмите на картинку, чтобы увеличить ее. Рисунок шотландского терьера как набор пикселей Мона Лиза как набор пикселей, с увеличением пикселей, составляющих один глаз

    Каждое изображение на мониторе компьютера представлено пикселями. Изображения на веб-странице сохраняются в файлах, которые, помимо данных изображения, содержат информацию о размере изображения, наборе используемых цветов, происхождении изображения и т. д. В зависимости от того, как именно сохраняется эта информация , мы называем их форматами изображений. GIF, JPEG, PNG и BMP — одни из самых известных форматов изображений. Подробнее о форматах изображений мы поговорим ниже. Сейчас мы сосредоточимся на количестве пикселей и представлении каждого пикселя и, следовательно, на размере файла изображения.

    Выше мы сказали, что количество каждого основного цвета — это число от 0 до 25510 или от 00 до FF16. Неслучайно это ровно один байт (8 бит). Байт — это удобный фрагмент компьютерной памяти, поэтому один байт был выделен для представления количества одного основного цвета. Таким образом, для представления одного пятна чистого цвета требуется 3 байта (24 бита).

    Поскольку каждый пиксель занимает 24 бита (3 байта), в зависимости от количества пикселей вашего устройства для хранения изображения может потребоваться много места.

    300 x 500 x 3 = 450 000 байт

    Это около 450 килобайт (сокращенно kB, "k" — строчная, а B — прописная; см. примечание к сокращениям) или почти полмегабайта. Это не только много места для хранения, но, что более важно, загрузка занимает значительное время, если только ваш модем не очень быстрый. Например, если у вас телефонный модем старого образца, который может обрабатывать только 56 кбит/с (56 кбит/с) = 7 кбит/с (7 кбит/с), вам потребуется немногим более 1 минуты для его загрузки (напомним, что 1 байт = 8 бит/с). биты). Это много времени.

    Телефонные модемы? Да, некоторые люди до сих пор пользуются телефонными модемами. Но очень популярны стали более быстрые DSL-модемы (от 128 кбит/с до 1500 кбит/с) и кабельные модемы (от 300 кбит/с до 6 000 кбит/с).

    Однако появление более высоких скоростей соединения сопровождается ростом числа веб-сайтов с контентом (фотографии с более высоким разрешением, песни, видео), который полностью потребляет дополнительную пропускную способность. Таким образом, ни у кого никогда не бывает достаточно пропускной способности сети, и разумно не тратить ее впустую. Если кто-то из вашей аудитории обнаружит, что ваш сайт загружается медленно, он перейдет на другой сайт.>

    1. При использовании модема на 56 кбит/с (56 000 битов в секунду) сколько времени вам потребуется, чтобы загрузить папку, содержащую все эти изображения?
    2. Проверьте текущую скорость подключения к Интернету с помощью этого теста скорости (например, подключитесь к серверу в Нью-Йорке). При такой скорости сколько времени вам потребуется, чтобы загрузить все изображения?

    Размер изображения и время загрузки

    В несжатом формате файла для хранения каждого пикселя требуется 24 бита (3 байта). Предположим, вы собираетесь сфотографировать всех своих 30 одноклассников для веб-сайта класса, используя камеру iPhone4. Согласно спецификациям телефона, его экран имеет разрешение 2592 x 1936 пикселей, что составляет около 5 миллионов пикселей или 5 МП (мегапикселей). Таким образом, если каждый пиксель занимает 3 байта, а фото с вашей камеры имеет разрешение 5 МП, то для хранения изображения вам потребуется 15 МБ (мегабайт). Для всех ваших одноранговых фотографий вам потребуется 30 x 15 МБ = 450 МБ.

    Представьте, что вы размещаете все эти фотографии на своем веб-сайте на одной странице (используя атрибуты width и height, чтобы они поместились на одном экране), а затем отправляете ссылку на эту страницу своим родителям.У них может быть среднее подключение к Интернету (например, Verizon предлагает 1–3 Мбит/с (мегабит в секунду) подписчикам без FiOS).

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

    размер содержимого (450 МБ) x 8 бит/байт / 1 МБ = 3600 секунд или 1 час.

    Если бы размер каждой из ваших фотографий составлял всего около 100 КБ (как мы требуем в некоторых ваших домашних заданиях), то время загрузки всех фотографий на странице составило бы 24 секунды.

    Итак, как мы можем сделать наши изображения такими маленькими? Есть два способа: изменение размера (уменьшение количества пикселей в изображении путем разумной обрезки) и сжатие (уменьшение необходимого количества битов на пиксель). Мы обсудим сжатие в следующем разделе.

    Сжатие

    Помимо уменьшения размеров изображений (меньше пикселей), что мы можем сделать, чтобы ускорить загрузку? Мы можем сжать файлы.

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

    Мы подробно рассмотрим один из видов сжатия без потерь — индексированный цвет (кодирование GIF), потому что он дает нам представление о видах идей и методов, которые важны при разработке представлений изображений. информация.

    Индексированный цвет

    <ПР>
  • нумерованный список цветов
  • какого цвета (номера) каждый пиксель
  • Пример: двухцветное изображение

    Вы можете увидеть общую схему в работе: мы создаем таблицу всех цветов, используемых на картинке. Сокращением для цвета является просто его индекс в таблице. Мы ограничим таблицу так, чтобы сокращения были не более 8 бит. Поскольку все сокращения заменяют спецификации 24-битного цвета, сокращение составляет максимум одну треть размера. В приведенном выше примере сокращение составляет 1/24 размера.

    Пример: четырехцветное изображение

    Как видите, сокращенная запись теперь состоит из двух битов вместо одного. Следовательно, для 150 000 пикселей требуется 300 000 бит или 300 000/8 = 37 500 байт или около 37,5 КБ. Очевидно, что это примерно в два раза больше, чем в предыдущем примере, поскольку каждое сокращение теперь в два раза больше. Тем не менее, он все равно намного меньше несжатого файла размером 450 КБ.

    Как насчет размера палитры? Теперь это тоже в два раза больше. Четыре записи по 3 байта каждая увеличивают размер файла на 12 байт, что является незначительным увеличением до 37,5 КБ.

    Вы можете видеть, что количество битов, необходимых для каждого пикселя, является ключевым количеством. Это количество называется битами на пиксель или «bpp». Его также часто называют "битовой глубиной", так что размер файла изображения равен ширине x высоте x битовой глубине, как если бы это был физический трехмерный блок.

    Наконец, мы можем сформулировать правило:

    Разрядность изображения должна быть достаточно большой, чтобы количества строк в таблице хватило для всех цветов. Если битовая глубина d, количество строк в таблице равно 2 d .

    Вот точное соотношение, а также размер изображения 300 x 500:

    Сопоставление битовой глубины с количеством цветов
    битовая глубинамаксимальное количество цветов размер файла изображения 300x500
    12 18kB
    24 37kB
    38 55 КБ
    41673 КБ
    53291 КБ
    664110 КБ
    7128128kB
    8256147 КБ

    Упражнение 3

    <УЛ>
  • Сколько байтов требуется для представления этого изображения, если оно черно-белое? Не забудьте представить таблицу цветов.
  • Сколько байтов, если изображение использует 4 цвета?
  • Сколько байтов, если изображение использует 16 цветов?
  • Сколько байтов, если изображение использует 17 цветов?
  • Подводя итог, можно уменьшить размер файла изображения, используя меньше цветов. Конечно, это может снизить качество вашего изображения. Это компромисс.

    Индексированный цвет GIF

    Формат файла GIF (т. е. представление изображения) — наиболее известный пример формата индексированного цвета. Вот как это работает: представьте художника-росписчика, который придет к вам домой и нарисует на вашей стене все, что вы захотите. Но есть одна загвоздка: она приедет к вам домой только один раз, а в ее фургоне всего 256 банок с краской. У нее на складе 16 миллионов банок с краской, и вы можете выбрать любые 256, какие захотите, но у вас не может быть фрески с более чем 256 разными цветами.

    Это основная идея изображений GIF и индексированного цвета. -->

    Вычисление размера файла

    Мы узнали, как работает индексированный цвет и как он влияет на размер файла. Это важно не только для теоретического понимания того, почему представления имеют значение, но и для практической полезности понимания того, как уменьшить размеры ваших изображений. В этом разделе мы рассмотрим, как вычислить приблизительный размер изображения с индексированными цветами. (Индексированный цвет — это один из приемов, используемых в файлах GIF, хотя в файлах GIF используются и другие приемы.) Зачем мы это делаем? Потому что он объединяет все концептуальные вопросы в один небольшой расчет.

    Ключевой концепцией вычислений является битовая глубина изображения. Прочтите на стр. 19 определение битовой глубины. Это количество битов, необходимое для представления желаемого количества цветов. Помните, что количество цветов равно 2 d , где d — разрядность. Это экспоненциальная зависимость. Добавление всего одного бита к битовой глубине удваивает количество цветов, которые вы можете иметь.

    1. пиксели (представленные их сокращенными значениями, каждый из которых имеет размер, равный битовой глубине), и
    2. палитра (в которой для каждого сокращения дается полноцветное определение).

    Наконец, поскольку размер файла обычно большой (тысячи или миллионы байт), мы делим его на 1000 или 1 000 000, чтобы преобразовать в килобайты или мегабайты, в зависимости от ситуации.

    Мы продолжим обсуждение расчета размера файла в лабораторных и домашних заданиях.

    В килобайте 1024 байта, а в мегабайте 1024 килобайта, поэтому документ размером 1 КБ будет содержать 1024 байта данных или 1024 символа текста и другой программной информации, описывающей форматирование документа и другие характеристики, чтобы его можно было открыть. и используется программным приложением, таким как Adobe Acrobat или Microsoft Word.

    Изображения представлены на экране в виде пикселей или цветных точек, но могут быть созданы в различных форматах, требующих для хранения файлов самых разных размеров. Для каждого изображения требуется разное количество байтов на пиксель, чтобы определить цвет и расположение каждого пикселя на экране. Черно-белые изображения требуют меньше места, чем изображения в оттенках серого или цветные из-за количества байтов, необходимых для уникального описания каждого цвета. Изображения могут быть выражены во многих форматах, и некоторые большие форматы файлов, такие как изображения TIFF, являются "без потерь" - это означает, что каждый пиксель (точка цвета на вашем экране) получает свой собственный набор байтов для его описания. При равных цветах и ​​других факторах изображение размером 100x100 пикселей (всего = 1000 пикселей) требует примерно в 10 раз больше места для хранения, чем изображение 10x10 пикселей (всего = 100 пикселей). Для сравнения, для представления одного символа текста, занимающего на экране пространство размером 10 x 10 пикселей, обычно требуется всего один байт.

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

    Вы обнаружите, что полная страница электронного текста значительно меньше, чем отсканированное изображение TIFF того же текста, когда оно добавляется в файл PDF.

    Разница в размере файла txt выше представляет собой то, что добавлено, чтобы сделать его файлом PDF.

    Файл PDF, содержащий 8-битный файл TIFF 10x10 с буквой "a" (такой же размер на экране, как и исходный текст)

    Читайте также: