Кодирование изображений
Картинка на экране — это сетка точек, и зная их количество и «вес» каждой точки, мы можем точно посчитать, сколько байт займёт изображение.
Когда вы фотографируете на телефон, видите надпись «снимок весит 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 | Где встречается |
|---|---|---|
| 1 | 2 | чёрно-белое (монохром) |
| 2 | 4 | простые иконки |
| 4 | 16 | старые игры, EGA |
| 8 | 256 | GIF, индексированные изображения |
| 16 | 65 536 | режим High Color |
| 24 | 16 777 216 | True 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. Это и есть смысл палитры — экономия места там, где богатая цветовая гамма не нужна.
Как решать такие задачи
Алгоритм всегда один и тот же:
- Если дана палитра (число цветов N) — найдите глубину
k = log₂ N(то есть «в какую степень возвести 2, чтобы получить N»). - Посчитайте число пикселей: ширина × высота.
- Умножьте на k — получите объём в битах.
- Разделите на 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 — Кбайт.