Работа с BMP через imageio
Обрабатываем картинки
Картинки в Python можно обрабатывать с помощью модуля imageio.
Пример картинки: Яндекс.Диск.
Установка
pip install imageio
Мы установим imageio, но также установится numpy (это зависимость imageio).
Давайте разберём код:
Импорты
from numpy import uint8 as u8, ndarray
from imageio.v2 import imread, imwrite # без .v2 выдаст предупреждение
Здесь мы импортируем нужные функции и классы.
uint8 - это тип данных для целых чисел в диапазоне от 0 до 255, мы используем его, чтобы хранить значения яркости цветовых каналов.
ndarray - это тип данных для двумерных масссивов.
imread - функция для чтения изображения.
imwrite - функция для записи изображения.
Чтение изображения
im: ndarray = imread("image.bmp")
h: int = len(im)
w: int = len(im[0])
h: int = im.shape[0] # способ с помощью numpy
w: int = im.shape[1]
print("Ширина:", w)
print("Высота:", h)
bpp = 3 # bytes per pixel, в BMP - 3 (R, G, B)
size = w * h * bpp
print(f"Размер BMP-файла: {size / 1024 / 1024:.2f} МБ")
Мы используем функцию imageio.imread для чтения изображения, она возвращает двумерный массив, состоящий из цветовых каналов.
Дальше мы используем свойство shape для получения ширины и высоты изображения.
Исходя из того, что наше изображение типа BMP, элементы массива - 3 цветовых канала (R, G, B).
Создание транспонированного изображения
im2 = [[0 for i in range(h)] for j in range(w)]
Тут мы создаём транспонированный массив. В нём h столбцов, и w строки. В обычном изображении было бы h строк и w столбцов.
Мы заполняем массив нулями, это не имеет значения.
Обработка изображения
for ix in range(w):
for iy in range(h):
r, g, b = map(int, im[iy][ix])
v = (r + g + b) // 3
im2[ix][iy] = [u8(v), u8(v // 2), u8(v // 4)]
Мы проходим по каждому пикселю обычного изображения, извлекаем значения цветовых каналов (r, g, b) и их среднюю яркость (v).
Далее мы проходим по массиву im2 (поменяв местами столбцы и строки) и записываем в него обновлённые значения цветовых каналов: оставляем красный, уменьшаем зеленый в два раза, уменьшаем синий в четыре раза. В результате мы получаем коричневое изображение, так как красного и зеленого больше всего.
Запись изображения
imwrite("imagexl.bmp", im2, format="bmp")
Мы используем функцию imageio.imwrite для записи изображения в формате bmp.