#python #image-processing #bitmap
#питон #обработка изображений #растровое изображение
Вопрос:
Я пишу чистый декодер/кодер растровых изображений python. У меня возникли проблемы с поиском наилучшего способа хранения данных пикселей в памяти, чтобы я мог выполнить некоторую обработку изображения. Вот мой текущий код:
image.seek(0) file_type = image.read(2) print(f"File Type: {file_type.decode('ascii')}") meta = image.read(12) file_size, _, _, offset = unpack("lt;I2HI", meta) print(f"File Size: {file_size}") print(f"Header Offset: {offset}") image_header = image.read(40) header_size, image_width, image_height, color_planes, bits_per_pixel, compression, image_size, horizontal_reso, vertical_reso, color_palette, important_color = unpack("lt;3I2h2I4I", image_header) print(f"Header size: {header_size}") print(f'Width: {image_width} | Height: {image_height}') print(f"Bits per pixel: {bits_per_pixel}") print(f"Image size: {image_size}") print(f"Horizontal reso: {horizontal_reso} | Vertical reso: {vertical_reso}") print(f"Color palette: {color_palette}") raw_image = image.read() def calculate_row_size(bits_per_pixel, image_width): return math.ceil((bits_per_pixel * image_width)/32)*4 def calculate_row_padding(bits_per_pixel, image_width): return ((bits_per_pixel//8) * image_width) % 4 def calculate_pixel_array_size(row_size, image_height): return row_size * abs(image_height) def calculate_number_of_rows(row_size, pixel_array_size): return pixel_array_size//row_size row_size = calculate_row_size(bits_per_pixel, image_width) pixel_array_size = calculate_pixel_array_size(row_size, image_height) number_of_rows = calculate_number_of_rows(row_size, pixel_array_size) row_pad = calculate_row_padding(bits_per_pixel, image_width) print(f"Row size: {row_size}") print(f"Pixel array size: {pixel_array_size}") print(f"Number of rows: {number_of_rows}") print(f"Padding size: {row_pad}") final_image = b'' def chunk(data, n): for i in range(0, len(data), n): yield i, data[i:i n] for i, data in chunk(raw_image, row_size): for i, rgb in chunk(data, 3): avg = sum(rgb)//3 final_image = avg.to_bytes((avg.bit_length() 7)//8, 'little')
В конце концов, я пытаюсь преобразовать в оттенки серого (очень неэффективно). Моей мыслью было создать список списков, в которых данные пикселей будут храниться в стиле массива NumPy. Любой вклад был бы полезен.
Комментарии:
1. использовать
numpy
. очень удобно. вы могли бы побеспокоиться о встроенномarray
типе python (и модуле), но эх. — ввод-вывод изображения для обмана/проверки можно выполнить с помощью OpenCV, PIL/pillow, scikit-image, … и все они совместимы с numpy2. Я знаю, что могу легко сделать это с numpy. Я просто пытаюсь избежать использования каких-либо библиотек.
3. можно обмануть, если вы используете его только в качестве контейнера. вы могли бы написать свой собственный класс, который хранит все это в bytearray (встроенный тип python).