# Переводит список байт в соответствующее ему число
def bytesToNumber(bs):
    x = 0
    for b in reversed(bs):
        x = x * 256 + b
    return x
 
 
# Возвращает ближайшее к x значение из отрезка [mn, mx]
def fit(x, mn, mx):
    return min(max(x, mn), mx)
 
 
class Color:
    def __init__(self, r, g, b):
        self.r, self.g, self.b = r, g, b
 
    # Доступ к компоненте цвета по индексу (c[1])
    def __getitem__(self, k):
        return [self.r, self.g, self.b][k]
 
    # Запись в компоненту цвета по индексу (c[1] = 126)
    def __setitem__(self, k, v):
        if k == 0:
            self.r = v
        elif k == 1:
            self.g = v
        elif k == 2:
            self.b = v
 
 
class Image:
    def __init__(self, header, data):
        self.header = header
        self.data = data
        self.width = bytesToNumber(header[18:22])
        self.height = bytesToNumber(header[22:26])
        self.row_size = (3 * self.width + 3) // 4 * 4
 
    # Возвращает копию изображения
    def copy(self):
        return Image(self.header[:], self.data[:])
 
    # Возвращает цвет пикселя с координатами (x, y)
    def getPixel(self, x, y):
        offset = y * self.row_size + 3 * x
        return Color(
            self.data[offset + 2], self.data[offset + 1], self.data[offset])
 
    # Устанавливает цвет пикселя с координатами (x, y) в color
    def setPixel(self, x, y, color):
        offset = y * self.row_size + 3 * x
        self.data[offset + 2] = fit(int(color.r), 0, 255)
        self.data[offset + 1] = fit(int(color.g), 0, 255)
        self.data[offset] = fit(int(color.b), 0, 255)
 
    # Сохраняет изображение в файл file_name
    def write(self, file_name):
        with open(file_name, "wb") as f:
            f.write(bytes(self.header))
            f.write(bytes(self.data))
 
 
# Читает изображение из файла file_name
def readImage(file_name):
    with open(file_name, 'rb') as f:
        raw_data = f.read()
        image_data_offset = bytesToNumber(raw_data[10:14])
        return Image(
            list(raw_data[:image_data_offset]),
            list(raw_data[image_data_offset:]))
 
 
image = readImage('sample.bmp')
result = image.copy()
 
for y in range(image.height):
    for x in range(image.width):
        c = image.getPixel(x, y)
        # Здесь мог бы быть ваш код
        result.setPixel(x, y, new_color)
 
result.write('result.bmp')
