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