Постараюсь подробно "на пальцах" рассказать, как изображение записывается в память машины.
Итак. Главный тезис: для того, чтобы послать нашему другу мемчик или сохранить демотиватор себе на телефон, требуется изобразить его в "ноликах и единичках".
О памяти машины
Потому что память машины устроена именно так: она содержит сплошняком ячейки, в которых может быть только "0" или "1". Конечно, там не цифры записаны. Они только называются "логический ноль" или "логическая единица". На самом деле, всё зависит от технологии, по которой изготовлена память машины. Например, кучу лет назад (даже "олды" не все припомнят) существовали перфокарты. Такие картонные карточки с цифрами. У них ещё уголок один был срезан:
В качестве логических нулей и единиц использовались дырочки. 864 дырочки или "недырочки". Технология, вообще-то, не очень. Если оператор ошибался в одной дырочке, то карту приходилось менять полностью. Ну, или заклеивать/прорезать лезвием. В современных машинах, конечно, и метод другой, и количество немного больше (в Вкипедии написано, что "кинчик" на 1 гигабайт, в прямом смысле, весил бы 22 тонны, если бы его на перфокартах пробивали).
В разных ситуациях словом бит называют:
- одни значок (дырочка-недырочка, ноль-один)
- одно место, на котором может быть записан либо ноль, либо один
- единицу измерения количества информации
Очень важная деталь. Биты (2) сгруппированы в сегменты по 8 штук. Такие сегменты называются байты. Аналогично битам, у слова "байт" есть несколько значений. Важно то, что машина не может прочитать один бит. За раз ей нужно прочитать целый байт, а только потом из него выделить бит. То же с записью - за раз можно записать только один целый байт, но не бит. Если нам надо поменять один бит, мы должны считать весь байт, заменить там бит с помощью логических операций, перезаписать байт обратно.
Про изображения
Существует масса способов записать картинку только ноликами и единичками. В школе проходят растровый и векторный. К векторному, возможно, я обращусь ещё, а вот про растровый расскажу подробнее. Суть проста: изображение разбивается на одинаковые клеточки. Эти клеточки называются "пиксели" или "пикселы". Кто как привык. Каждый пиксель имеет один единственный цвет. Получается мозаика.
Самый примитивный способ записи в ноликах и единичках - просто подряд записать цвет пикселей. 0- белый, 1 - зелёный:
Чем мельче пиксели, чем их больше, тем "плавнее" будет линия на картинке.
Кто вышивает крестиком - точно это всё знают.
О количестве цветов
Наша картинка имеет только 2 цвета - белый и зелёный. Такой режим называется "монохромный". Если мы пожелаем ещё цвета использовать, то надо что-то придумывать с их записью. Записывать "1" в красном квадрате бессмысленно, потому что при отрисовке на экране, машина не отличит "красную" единицу от "зелёной" и всё закрасит одним цветом. "Двоек" у нас не существует.
Единственный хороший вариант - вместо "0" или "1" писать в каждой клетке "00", "01", "10" или "11". Это позволит нам использовать 4 цвета.
Если поразмыслить, то можно в любой пиксель напихать сколько угодно ноликов и единичек. Тут главное - во все одинаково, иначе возникнет трудность с прочтением сплошной портянки (хотя, и для разных есть хитрые способы)
Если мы будем записывать по 1 символу на пиксель (1 бит/px), получим всего два цвета. 2 символа уже даст нам 4 цвета. Запишу-ка я такую табличку:
Для каждого количества бит на пиксель указано количество возможных цветов и даже их уникальные коды. Вырисовывается классная формула (известная)
О дисплеях и камерах
В работе с изображением участвуют: память машины (там оно хранится) и дисплеи с камерами (они показывают нам изображение или записывают в память). Примитивно говоря, дисплей состоит из ярких точек, в каждой из которых есть три "лампочки". Красная, зелёная и синяя. От того, какие из них горят, зависит и цвет, который мы видим:
Например, если горят красная и зелёная, мы видим жёлтый.
При таком подходе к дисплею удобно выполнять кодирование в формате 3 бита на пиксель: первый бит отвечает за красный цвет, второй - за зелёный, а третий - за синий. Тогда жёлтый будет закодирован как RGB"110". Наша табличка обретёт более конкретный смысл:
Для дисплея очень удобно делать 3 бита на пиксель, но это неудобно для памяти машины. Я уже говорил, что машина читает и пишет байтами. Трёхбитная палитра в байты не впишется: мы можем записать в один байт два пикселя, а третий не влезет. Можно оставить 2 бита пустыми или записать туда часть пикселя:
Оба варианта очень плохи, потому что в первом случае куча памяти будет не использована (там записаны единицы), а во втором случае для отрисовки первых двух пикселей можно будет обойтись чтением только первого байта, а для третьего пикселя придётся прочитать оба байта, выделить из них нужные биты и снова склеить. Тут ещё товарищи подсказывают, что можно сделать три байта: в первом только красные части, во втором только зелёные, а в третьем только синие. Так, одновременным чтением трёх байт мы сможем разом отрисовать 8 пикселей. Но разбивать 3 байта на биты...
Очень хорошо в память машины вписывается 4х-битная палитра (по два пикселя в байт). Инженеры тут предлагают такую схему A-R-G-B. Яркость-Красный-Зелёный-Синий.
Немного истории
Именно такую палитру мы видим в старых 16-цветных системах (windows 3.11, например, под нее был "заточен", windows 95 и 98 могли работать с такой)
А как же полутона? Человеческий глаз видит десятки тысяч оттенков! А тут всего 16.
Формат дисплеев довольно быстро развился до 16777216 оттенков на экране. По 24 бита на каждый пиксель. Первый байт указывал яркость красной лампочки, второй - яркость зелёной, а третий - синей. Получалось по 256 градаций каждого цвета. Но обработка таких изображений была проблематичной. Особенно, для маломощных систем типа телефонов (не смартфоны еще, а телефоны) и карманных игровых приставок.
На старых компьютерах использовалась система 256 цветов: из 16 миллионов выбирались эти 256 и каждому назначался 8-битный код. Таким образом, на экране одновременно можно было наблюдать только 256 цветов. Но и система успевала обрабатывать. Хотя, не всегда. В windows 95 и 98 наблюдался цветовой сбой при переключении полноэкранных приложений. Попросту цветовая таблица не очищалась:
Как это ни странно, очень распространена и по сей день схема кодирования 5-6-5. 16 бит на пиксель. Хоть 16 и не делится нацело на 3 (чтобы упихать в 2 байта информацию об одном пикселе), но нам предлагают использовать 5 бит под красный (32 градации), 6 бит под зелёный (64 градации) и остальные 5 бит - под синий. Зеленого больше, потому что человеческий глаз воспринимает зеленый цвет лучше прочих.
Ну, и наши современные телефоны (смартфоны уже) используют все 16777216 цветов, кодируя каждый пиксель с помощью 24 бит. Примерно так:
И дополнительно о сжатии и прозрачности
Прямое кодирование в ноликах и единичках "жрёт" очень много памяти. Так, скриншот экрана 1920*1080 занимал бы 6 мегабайт. Для экономии места используют разные варианты сжатия. От жадных кодов (gif) до сложных матричных алгоритмов (jpeg). Многие изображения имеют слои, которые накладываются друг на друга. Их можно показывать один за другим (gif-анимация). А можно накладывать, как при классической анимации. Но для этого каждому слою надо указать не только 3 главных цвета, но и прозрачность. Приходится использовать 32-битную палитру RGB-α. Здесь дополнительный "канал" идёт на 256 уровней прозрачности каждого пикселя.
Заключение
Я рассмотрел довольно популярные способы кодирования изображений, но далеко не все. Надеюсь, этого будет достаточно, чтобы получить первое представление о кодировании изображений.