Задание 7: кодирование графики и звука
Задание 7 (базовый уровень): считаем, сколько памяти займут картинка и звук.
Задание 7 проверяет умение определять информационный объём растрового изображения и звукового (аудио) файла по их параметрам. Это прямое применение алфавитного подхода.
Что проверяет задание
В задании дают параметры файла (для картинки — размеры и число цветов; для звука — частоту, глубину, каналы, длительность) и просят найти объём в байтах, Кбайтах или Мбайтах — либо, наоборот, восстановить один из параметров по известному объёму. Всё решается двумя формулами.
Растровое изображение
Растровое изображение — это сетка пикселей. Каждый пиксель кодируется i битами, где i = log2N, а N — количество цветов в палитре (глубина цвета). Объём всего изображения:
I = W · H · i (бит)
W, H — ширина и высота в пикселях
i — глубина цвета (бит на пиксель), i = log2(N)
Разберём пример. Рисунок размером 1024×768 пикселей использует палитру из 256 цветов. Каков объём файла в Кбайтах (без сжатия)?
import math
W, H = 1024, 768
N = 256 # число цветов
i = int(math.log2(N)) # бит на пиксель
I_bit = W * H * i # объём в битах
I_kb = I_bit / 8 / 1024 # переводим бит -> байт -> Кбайт
print("бит на пиксель:", i)
print("всего пикселей:", W * H)
print("объём, Кбайт:", int(I_kb))
Вывод:
бит на пиксель: 8 всего пикселей: 786432 объём, Кбайт: 768
Звуковой файл
Цифровой звук получают, измеряя громкость много раз в секунду. Объём аудио зависит от четырёх параметров:
I = f · b · channels · t (бит)
f — частота дискретизации (Гц = измерений в секунду)
b — глубина кодирования (бит на одно измерение)
channels — число каналов (моно=1, стерео=2, квадро=4)
t — длительность в секундах
Пример. Стереозапись (2 канала) оцифрована с частотой 48 000 Гц и глубиной 16 бит, длительность 30 секунд. Найти объём в Мбайтах.
f = 48000 # Гц
b = 16 # бит на отсчёт
channels = 2 # стерео
t = 30 # секунд
I_bit = f * b * channels * t
I_mb = I_bit / 8 / 1024 / 1024
print("объём, бит:", I_bit)
print("объём, байт:", I_bit // 8)
print("объём, Мбайт:", round(I_mb, 2))
Вывод:
объём, бит: 46080000 объём, байт: 5760000 объём, Мбайт: 5.49
Обратные задачи: «во сколько раз» и «найди параметр»
Чаще дают не «посчитай объём», а «во сколько раз изменится объём, если...» или «найди частоту, при которой объём стал таким-то». Здесь побеждает приём отношения: объём прямо пропорционален каждому параметру. Если глубину цвета увеличили с 8 до 24 бит, объём вырос ровно в 3 раза — независимо от размеров картинки.
Пример. Несжатое изображение занимало 900 Кбайт при палитре 256 цветов. Сколько займёт то же изображение при палитре 16 цветов?
import math
V1 = 900 # Кбайт при 256 цветах
i1 = int(math.log2(256)) # 8 бит
i2 = int(math.log2(16)) # 4 бита
# объём пропорционален числу бит на пиксель
V2 = V1 * i2 / i1
print("было бит/пиксель:", i1, "стало:", i2)
print("новый объём, Кбайт:", int(V2))
Вывод:
было бит/пиксель: 8 стало: 4 новый объём, Кбайт: 450
Восстановление параметра по объёму
Самый каверзный подтип задания 7 — когда известен объём, а найти нужно один из параметров. «Изображение размером 640×480 без сжатия заняло 153 600 байт. Сколько цветов в палитре?» Идём от объёма к глубине цвета:
W, H = 640, 480
I_byte = 153600
I_bit = I_byte * 8
i = I_bit // (W * H) # бит на пиксель
N = 2 ** i # число цветов
print("всего пикселей:", W * H)
print("бит на пиксель:", i)
print("цветов в палитре:", N)
Вывод:
всего пикселей: 307200 бит на пиксель: 4 цветов в палитре: 16
Ловушка: если деление «бит на пиксель» не даёт целого числа, значит в условии заложено округление или другой размер — перечитайте задачу. Здесь 4 бита дают палитру в 16 цветов. Метод универсален: объём → биты → разделить на число «элементов» (пикселей или отсчётов) → получить параметр на один элемент.
Видео как кадры изображений
Иногда задание 7 затрагивает видео — это просто последовательность кадров-изображений. Объём = (объём одного кадра) × (число кадров) = (объём кадра) × (частота кадров × длительность). Принцип тот же, добавляется один множитель:
import math
W, H = 800, 600
colors = 65536 # 2 в степени 16
i = int(math.log2(colors)) # бит на пиксель
fps = 25 # кадров в секунду
seconds = 10
frame_bits = W * H * i
total_bits = frame_bits * fps * seconds
print("бит на кадр:", frame_bits)
print("объём видео, Мбайт:", round(total_bits / 8 / 1024 / 1024, 1))
Вывод:
бит на кадр: 7680000 объём видео, Мбайт: 228.9
Типичные ловушки
- Число цветов ≠ число бит. 256 цветов — это 8 бит, а не 256 бит. Всегда берите log2.
- Каналы. «Стерео» = умножить на 2, «квадро» = на 4. Про каналы часто забывают.
- Кбайт vs Кбит. Внимательно к единице в ответе: иногда требуют именно биты или Кбит.
- Частота в кГц. Если дана частота 48 кГц — это 48 000 Гц, переводите в герцы.
- Округление вверх для глубины цвета, если число цветов не степень двойки (например, 100 цветов → 7 бит).
- Обратные задачи. «Найди параметр по объёму» — переведите объём в биты и поделите на число элементов; деление обязано быть целым.
Итог
- Изображение: I = W · H · i, где i = log2(число цветов).
- Звук: I = f · b · channels · t.
- В задачах «во сколько раз» используйте пропорциональность — не считайте абсолютный объём целиком.