Задание 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.
  • В задачах «во сколько раз» используйте пропорциональность — не считайте абсолютный объём целиком.
Проверьте себя
1. Изображение 800×600 использует 16 цветов. Сколько бит на один пиксель?
A2
B4
C8
D16
2. Во сколько раз вырастет объём звука, если перейти со стерео (2 канала) на квадро (4 канала), не меняя прочие параметры?
AВ 1,5 раза
BВ 2 раза
CВ 4 раза
DНе изменится
3. Частота дискретизации в формуле объёма звука измеряется в...
Aбитах на отсчёт
Bгерцах (отсчётов в секунду)
Cканалах
Dсекундах
Поддержать проект