Кодирование изображений

Картинка на экране — это сетка точек, и зная их количество и «вес» каждой точки, мы можем точно посчитать, сколько байт займёт изображение.

Когда вы фотографируете на телефон, видите надпись «снимок весит 3,2 МБ». Откуда берётся это число? Почему одна картинка занимает килобайты, а другая — мегабайты, хотя на экране они одного размера? Ответ прячется в том, как компьютер хранит изображение: он разбивает его на крошечные одноцветные точки и записывает цвет каждой точки числом. Чем больше точек и чем богаче палитра цветов, тем больше места нужно.

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

Пиксель и разрешение

Слово «пиксель» происходит от английского picture element — «элемент картинки». Если сильно увеличить любую фотографию, вы увидите, что она состоит из квадратиков — это и есть пиксели. Каждый из них имеет ровно один цвет.

Сколько всего пикселей в картинке, говорит её разрешение — пара «ширина × высота». Например, разрешение 800 × 600 означает 800 пикселей по горизонтали и 600 по вертикали. Перемножив, получаем общее число точек:

800 × 600 = 480 000 пикселей

Это уже почти полмиллиона точек — а ведь это маленькая картинка по нынешним меркам.

Глубина цвета

Каждому пикселю нужно сообщить его цвет, а компьютер хранит всё числами в битах. Глубина цвета k — это сколько бит отводится под цвет одного пикселя. И тут работает то же правило, что и для любых данных: k бит кодируют N = 2^k различных значений, то есть N различных цветов.

Число цветов N и глубина цвета k связаны формулой N = 2^k. Наоборот: чтобы закодировать N цветов, нужно k = log₂ N бит.

Таблица: глубина цвета и число цветов

Чем больше бит на пиксель, тем больше оттенков можно различить — но тем «тяжелее» картинка.

Глубина k (бит/пиксель)Число цветов N = 2^kГде встречается
12чёрно-белое (монохром)
24простые иконки
416старые игры, EGA
8256GIF, индексированные изображения
1665 536режим High Color
2416 777 216True Color (RGB по 8 бит)

Самый частый случай — 24 бита: по 8 бит на каждую из трёх составляющих красного, зелёного и синего (RGB). 8 бит дают 256 уровней яркости каждого канала, а 256 × 256 × 256 = 16 777 216 цветов — больше, чем способен различить человеческий глаз.

Палитра

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

Например, если в палитре 256 цветов, то каждому пикселю достаточно номера от 0 до 255 — а это ровно один байт, то есть k = 8 бит. Размер палитры задаёт глубину цвета: палитра из N цветов требует k = log₂ N бит на пиксель.

Объём изображения

Теперь соберём всё вместе. Объём (информационный «вес») растрового изображения — это число пикселей, умноженное на «вес» одного пикселя в битах:

V = ширина × высота × k (в битах), где k — глубина цвета (бит на пиксель).

Чтобы перевести результат в байты, делим на 8; чтобы в килобайты — ещё раз делим на 1024. Разберём это на примерах.

Пример 1. Фото 800 × 600, True Color (k = 24)

пикселей: 800 × 600 = 480 000
объём в битах: 480 000 × 24 = 11 520 000 бит
в байтах: 11 520 000 ÷ 8 = 1 440 000 байт
в Кбайт: 1 440 000 ÷ 1024 = 1406,25 Кбайт

Полмиллиона точек, по 3 байта каждая — и вот картинка уже занимает почти полтора мегабайта. Именно поэтому фотографии сжимают (например, в JPEG).

Пример 2. Картинка 1024 × 768 с палитрой из 256 цветов

256 цветов — это k = log₂ 256 = 8 бит на пиксель.

пикселей: 1024 × 768 = 786 432
объём в битах: 786 432 × 8 = 6 291 456 бит
в байтах: 6 291 456 ÷ 8 = 786 432 байта
в Кбайт: 786 432 ÷ 1024 = 768 Кбайт

Пример 3. Иконка 640 × 480 на 16 цветов

16 цветов — это k = log₂ 16 = 4 бита на пиксель.

пикселей: 640 × 480 = 307 200
объём в битах: 307 200 × 4 = 1 228 800 бит
в байтах: 1 228 800 ÷ 8 = 153 600 байт
в Кбайт: 153 600 ÷ 1024 = 150 Кбайт

Калькулятор объёма изображения

Запустите программу ниже: она по ширине, высоте и глубине цвета считает объём картинки в битах, байтах и Кбайтах. Поменяйте значения width, height и depth и посмотрите, как «вес» взлетает при росте глубины цвета.

width = 800     # ширина в пикселях
height = 600    # высота в пикселях
depth = 24      # глубина цвета k, бит на пиксель

pixels = width * height          # всего пикселей
bits = pixels * depth            # объём в битах: V = W * H * k
bytes_ = bits / 8                # 1 байт = 8 бит
kbytes = bytes_ / 1024           # 1 Кбайт = 1024 байта

print("Пикселей:", pixels)
print("Цветов в палитре: 2^" + str(depth), "=", 2 ** depth)
print("Объём:", bits, "бит")
print("Объём:", bytes_, "байт")
print("Объём:", kbytes, "Кбайт")

Вывод программы:

Пикселей: 480000
Цветов в палитре: 2^24 = 16777216
Объём: 11520000 бит
Объём: 1440000.0 байт
Объём: 1406.25 Кбайт

Попробуйте заменить depth = 24 на depth = 8: при той же картинке объём упадёт в три раза, потому что на каждый пиксель теперь уходит 1 байт вместо 3. Это и есть смысл палитры — экономия места там, где богатая цветовая гамма не нужна.

Как решать такие задачи

Алгоритм всегда один и тот же:

  1. Если дана палитра (число цветов N) — найдите глубину k = log₂ N (то есть «в какую степень возвести 2, чтобы получить N»).
  2. Посчитайте число пикселей: ширина × высота.
  3. Умножьте на k — получите объём в битах.
  4. Разделите на 8 — получите байты; затем на 1024 — получите Кбайт.

Частые ошибки

  • Забывают перевести палитру в биты. 256 цветов — это не 256 бит, а 8 бит (256 = 2⁸).
  • Путают «×8» и «÷8». Из бит в байты — делим на 8, из байт в биты — умножаем на 8.
  • Делят на 1000 вместо 1024. В информатике 1 Кбайт = 1024 байта, поэтому ответ берут именно через 1024.
  • Складывают ширину и высоту вместо умножения. Число пикселей — это произведение W × H, а не их сумма.

Коротко

  • Растровое изображение — это сетка пикселей; разрешение W × H задаёт их число.
  • Глубина цвета k — это число бит на пиксель; число цветов N = 2^k, а k = log₂ N.
  • Палитра из N цветов требует k = log₂ N бит на пиксель.
  • Объём: V = W × H × k бит; делим на 8 — байты, ещё на 1024 — Кбайт.
Проверьте себя
1. Что такое глубина цвета k в растровом изображении?
AЧисло пикселей в изображении
BЧисло бит, отводимое на цвет одного пикселя
CШирина изображения в сантиметрах
DРазмер файла в килобайтах
2. Сколько цветов можно закодировать при глубине цвета 8 бит на пиксель?
A8
B64
C256
D1024
3. Палитра изображения содержит 16 цветов. Сколько бит отводится на один пиксель?
A2 бита
B4 бита
C8 бит
D16 бит
4. По какой формуле считают объём растрового изображения в битах?
AV = ширина + высота + k
BV = ширина × высота × k
CV = (ширина + высота) × k
DV = ширина × высота ÷ k
5. Изображение 1024 × 768 кодируется палитрой из 256 цветов. Каков его объём в Кбайтах?
A96 Кбайт
B384 Кбайт
C768 Кбайт
D6144 Кбайт
6. При переводе объёма из бит в байты что нужно сделать?
AУмножить на 8
BРазделить на 8
CУмножить на 1024
DРазделить на 1024
Поддержать проект