Чёрно-белое растровое изображение имеет размер 10x10 пикселей, сколько памяти займёт это изображение
Обновлено: 21.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 является важной информацией. Простым примером этого может быть установка для каждого четного столбца пикселей белого цвета, а для каждого нечетного — черного. Как вы могли бы сделать это с одномерным массивом пикселей? Как узнать, в каком столбце или строке находится тот или иной пиксель?
При программировании с пикселями нам нужно иметь возможность думать о каждом пикселе как о живущем в двухмерном мире, но продолжать получать доступ к данным в одном (поскольку именно так они становятся доступными для нас). Мы можем сделать это с помощью следующей формулы:
- Допустим окно или изображение с заданными значениями WIDTH и HEIGHT.
- Тогда мы знаем, что общее количество элементов массива пикселей равно WIDTH * HEIGHT.
- Для любой заданной точки X, Y в окне расположение в нашем одномерном массиве пикселей: РАСПОЛОЖЕНИЕ = X + Y * ШИРИНА.
Это может напомнить вам наш учебник по двумерным массивам. На самом деле нам нужно будет использовать ту же технику вложенных циклов for. Разница в том, что, хотя мы хотим использовать циклы for, чтобы думать о пикселях в двух измерениях, когда мы переходим к фактическому доступу к пикселям, они находятся в одномерном массиве, и мы должны применить формулу из приведенной выше иллюстрации.
Давайте посмотрим, как это делается.
Введение в обработку изображений
В предыдущем разделе были рассмотрены примеры, в которых значения пикселей задаются в соответствии с произвольным вычислением. Теперь мы рассмотрим, как мы можем установить пиксели в соответствии с найденными в существующем объекте PImage. Вот некоторый псевдокод.
- Загрузить файл изображения в объект PImage
- Для каждого пикселя в 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 определяется яркостью цвета. Более яркие цвета кажутся ближе к зрителю, а темные — дальше.
Этот калькулятор размера файла изображения поможет вам оценить размер файла несжатого растрового изображения при условии, что вы знаете разрешение изображения и его разрядность.
В этом калькуляторе вы узнаете, что такое файл изображения, что такое битовая глубина и чем отличается растровое изображение от векторного. Мы также покажем вам, как самостоятельно рассчитать размер файла изображения и как его объединение с аудиофайлом создает видеофайл. Продолжайте читать, чтобы узнать больше.
Что такое файл изображения?
Файл изображения — это цифровое представление изображения, и мы можем отобразить его на экране, таком как монитор компьютера или экран мобильного телефона. Файлы изображений содержат данные об атрибутах изображения, таких как присутствующие в нем цвета, интенсивность яркости и контрастности и многое другое. Эти данные хранятся в том, что мы называем битами. Подробнее о битах и компьютерных файлах можно узнать в разделе «Размеры компьютерных файлов» нашего калькулятора времени загрузки.
Файлы изображений могут иметь множество различных форматов, которые мы можем сгруппировать в две категории: растровые и векторные изображения. Файл растрового изображения содержит массив пикселей различных цветов, расположенных в сетке для формирования изображения. Пиксели — это крошечные точки, очень похожие на маленькие стежки X в схеме вышивки крестом, как показано на сравнительном рисунке ниже.
Изображения с большим количеством пикселей, как правило, показывают больше деталей и более высокое качество, особенно при попытке увеличить это изображение. Растровое изображение с большим количеством пикселей или разрешением позволяет нам значительно увеличить изображение, прежде чем мы начнем видеть отдельные пиксели, из которых оно состоит.
С другой стороны, векторные изображения состоят из таких атрибутов, как кривые, контуры, фигуры, толщина линий или штрихов, цвета и т. д., которые хранятся в формулах или уравнениях. В отличие от растровых изображений, которые хранят данные для каждого пикселя изображения, векторные изображения хранят данные в виде компиляции этих уравнений, представляющих каждый из указанных атрибутов. Вы можете думать об этом как о списке математических уравнений, которые мы можем изобразить на декартовой плоскости. Отображение векторного изображения похоже на построение графика этих уравнений на декартовой плоскости каждый раз, когда мы открываем файл изображения. Эти «графики» также обновляются каждый раз, когда мы масштабируем или масштабируем векторное изображение, благодаря чему мы всегда видим плавные линии и кривые с одинаковыми цветами и деталями.
Однако этот калькулятор размера файла изображения может определять размеры файлов только растровых изображений. Атрибуты векторного изображения могут невероятно сильно различаться, точно так же, как вы можете выразить математический график с помощью множества различных математических уравнений. Также стоит отметить, что этот калькулятор размера файла изображения определяет только размеры файлов несжатых изображений. Однако с помощью этого калькулятора можно даже приблизительно определить размер сжатого файла изображения, если известна результирующая разрядность файла изображения.
Размеры файлов изображений
Два параметра определяют размер файла растрового изображения: количество пикселей в изображении и битовая глубина каждого пикселя. Чтобы определить размер файла растрового изображения, мы должны перемножить эти переменные. Каждый пиксель растрового изображения обычно занимает от 1 до 8 бит для черно-белых изображений и от 8 до 64 бит для цветных изображений. И чем больше пикселей в изображении, тем больше данных оно хранит и тем больше размер его файла.
Выборка — это получение информации об изображении и попытка точного представления его в цифровой форме с точки зрения пикселей. Мы также можем сделать это со звуками, при этом мы записываем различные значения частоты и амплитуды для создания цифрового аудиофайла. Вы можете узнать больше о сэмплировании с помощью нашего калькулятора размера аудиофайла (см. ссылку в начале этой статьи).
Как рассчитать размер файла изображения?
Теперь, когда мы знаем, что такое битовая глубина и какое значение имеют пиксели при определении размера файла изображения, давайте рассмотрим пример, чтобы понять, как вычислять размеры файла изображения. Для нашего примера возьмем изображение размером, скажем, 640 пикселей (ширина) на 480 пикселей (высота) с глубиной цвета 24 бита. Чтобы определить количество пикселей этого изображения, мы умножаем размеры изображения в пикселях. Это похоже на получение площади прямоугольника, но на этот раз в пикселях:
количество пикселей = ширина изображения в пикселях * высота изображения в пикселях
количество пикселей = 640 пикселей * 480 пикселей
количество пикселей = 307 200 пикселей
Когда речь идет о большом количестве пикселей или разрешений, мы часто можем видеть "MP", что означает "мегапиксели". Мегапиксель — это единица измерения, равная одному миллиону пикселей. Что касается нашего рассчитанного количества пикселей, мы также можем сказать, что рассматриваемое нами изображение имеет размер примерно 0,3 мегапикселя. Продолжая наши расчеты, мы можем определить размер файла нашего изображения следующим образом:
размер файла изображения = количество пикселей * битовая глубина
Размер файла изображения = 307 200 пикселей * 24 бита на пиксель
размер файла изображения = 7 372 800 бит
Размер файла изображения = 7 372 800 бит * (1 байт / 8 бит) * (1 килобайт / 1000 байт)
размер файла изображения = 921,6 КБ (килобайт)
Обратите внимание, что рассчитанный нами размер файла изображения является лишь оценкой фактического размера описанного файла изображения. К компьютерным файлам обычно прикрепляются другие данные, включая, помимо прочего, дату создания файла, имя создателя и т. д. Но пока, в качестве оценки размера файла изображения, мы можем сказать, что он составляет около 921,6 КБ. В нашем примере выше мы также использовали десятичную систему СИ для преобразования размера данных, где 1000 байт эквивалентны 1 килобайту. Вы можете узнать больше об этом в нашем калькуляторе времени загрузки.
Хотите узнать больше?
Если вы хотите изучить размеры файлов и единицы измерения, используемые в цифровых файлах, вы можете воспользоваться нашим конвертером байтов. Там вы можете вводить размеры файлов и видеть их значение в других единицах размера файлов одновременно.
Bpp или бит на пиксель обозначает количество бит на пиксель. Количество различных цветов в изображении зависит от глубины цвета или количества битов на пиксель.
Кратко о математике:
Это похоже на игру с двоичными битами.
Сколько чисел может быть представлено одним битом.
Сколько двухбитовых комбинаций можно составить.
Если мы придумаем формулу для расчета общего количества комбинаций, которые можно составить из бит, она будет такой.
Где bpp обозначает количество бит на пиксель. Подставьте 1 в формулу, получите 2, подставьте 2 в формулу, получите 4. Она растет экспоненциально.
Количество разных цветов:
Теперь, как мы сказали в начале, количество различных цветов зависит от количества битов на пиксель.
Таблица некоторых битов и их цвета приведены ниже.
Бит на пиксель | Количество цветов | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 бит на пиксель | 2 цвета | |||||||||||||||
2 бита на пиксель | 4 цвета | |||||||||||||||
3 бита на пиксель | 8 цветов | |||||||||||||||
4 бита на пиксель | 16 цветов | |||||||||||||||
5 бит на пиксель | 32 цвета | |||||||||||||||
6 бит на пиксель | 64 цвета | |||||||||||||||
7 бит на пиксель | 128 цветов | |||||||||||||||
8 бит на пиксель | 256 цветов | |||||||||||||||
10 бит на пиксель | 1024 цвета | |||||||||||||||
16 бит на пиксель | 65536 цветов | |||||||||||||||
24 бит на пиксель | 16777216 цветов (16,7 миллиона цветов) | |||||||||||||||
32 бита на пиксель | 4294967296 цветов (4294 миллиона цветов) | тр> таблица>
Двоичные биты, доступные для цвета | Количество цветов, которые мы можем представить для пикселя |
---|---|
1 | 2, черно-белое |
2 | 4, например черный, белый и два серых |
3 | 8 |
4 | < td>16|
8 | 256 |
16 | 65536< /td> |
24 | 16,7 млн |
Изображения, которые вы делаете с помощью онлайн-приложений, таких как Instagram или Snapchat, скорее всего, будут храниться с глубиной цвета 16 или 24 бита. Это означает, что каждый пиксель может использовать один из 65 536 или 16,7 миллионов цветов соответственно. Вау!
Представьте, что вы работаете в компании по производству воздушных шаров и хотите создать цифровую рекламу, чтобы продемонстрировать все свои замечательные воздушные шары. Рекламу увидят миллионы людей со всего мира. Здесь использование 24 бит (16,7 миллионов цветов) для создания наиболее яркого и точного изображения в вашей рекламе имеет смысл! Качество изображения и небольшой размер файла — две конкурирующие цели, которые должны быть сбалансированы для каждого изображения.
Расчет размера
Размер файла может быть выражен как разрешение (ширина изображения, умноженная на высоту изображения), умноженное на разрядность (количество бит, необходимое для хранения цветов).
Файлы обычно также содержат некоторые метаданные, которые немного увеличивают размер файла, но пока мы их игнорируем.
Задание: Насколько велик ваш смайлик?
Ваша цель — найти общий размер изображения смайлика, включая его разрядность. Еще раз откройте изображение смайлика, которое вы скачали для первого действия этого шага.
Читайте также:
- Как назначить человека в Fallout 4 на PS4
- Какой тип памяти у USB-накопителя
- Какие редакторы компьютерного трехмерного моделирования вы знаете по технологии 7 класс
- Как установить Warface на ПК
- Как объединить файлы fb2 в один