Всё о Python

Работа с 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.