I'm creating a simple image editor in python using numpy for all the image transformations. I have encountered a problem with changing brightness - when I changed the brigtness to -255 or 255 I (obviously) lost all the information and changing brigthness back to 0 didn't give me the original image. I understand this behaviour but what if I want to get the original image instead?

My solution is keeping a copy of the image with default brightness, but this feels kinda ineffective as now I have two images to change - image_data and image_data_no_brightness with every transformation other than brightness change (rotations, mirroring, to negative, etc.).

Is there some more effective solution of this?

import numpy as np
from matplotlib.pyplot import imshow, imsave, imread
from PIL import Image

MIRROR_VERTICAL = 0
MIRROR_HORIZONTAL = 1


class ImageEditor:

def __init__(self):
    self.image_data = None
    self.image_data_og = None
    self.image_data_no_brightness = None

def load_data(self, image_path):
    # todo fix imread and imwrite to be compatible with png images
    self.image_data = np.asarray(Image.open(image_path).convert('RGB'))
    self.image_data.setflags(write=True)
    self.image_data_og = self.image_data.copy()
    self.image_data_no_brightness = self.image_data.copy()

def get_data(self):
    return self.image_data

def save_image(self, image_path):
    imsave(image_path, self.image_data)

def show(self):
    imshow(self.image_data, cmap='gray')

def reset(self):
    self.image_data = self.image_data_og.copy()
    self.image_data_no_brightness = self.image_data_og.copy()

def rotate(self, angle):
    assert angle % 90 == 0  # GUI shouldn't let this happen
    self.image_data = np.rot90(self.image_data, k=angle / 90)
    self.image_data_no_brightness = np.rot90(self.image_data_no_brightness, k=angle / 90)

def mirror(self, axis=MIRROR_HORIZONTAL):
    self.image_data = np.flip(self.image_data, axis=axis)
    self.image_data_no_brightness = np.flip(self.image_data_no_brightness, axis=axis)

def negative(self):
    self.image_data = 255 - self.image_data
    self.image_data_no_brightness = 255 - self.image_data_no_brightness

def brightness(self, change):
    # convert to int16 as uint8 values could overflow
    self.image_data = np.clip(np.int16(self.image_data_no_brightness) + change, 0, 255)
    # convert back to uint8
    self.image_data = np.uint8(self.image_data)

0 Answers