Using PIL to adjust color saturation of list of images. I receive no errors but the output does not reflect my changes

315 Views Asked by At

I'm working on a project in a Python course where I use PIL to take an image, make copies of it, adjust the color saturation of each copy, and display those copies on a canvas. The output should look like this: What output should look like

This is what my output currently looks like: My output

My code looks like this:

---Edit: Adding the original input image for context: Original Picture---

import PIL
from PIL import Image

# read image and convert to RGB
image=Image.open("readonly/msi_recruitment.gif")
image=image.convert('RGB')

# for first row, images 1-3, adjust blue channel (3rd channel) from darker to lighter

# adjust first image, very blue
r, g, b = images[0].split()
b = b.point(lambda i: i * 0.1)
result = Image.merge('RGB', (r, g, b))
result.save('result.gif')
        
# adjust second image, not quite as blue but still pretty blue
r, g, b = images[1].split()
b = b.point(lambda i: i * 0.5)
result = Image.merge('RGB', (r, g, b))
result.save('result.gif')

# adjust third image, barely more blue than original
r, g, b = images[2].split()
b = b.point(lambda i: i * 0.9)
result = Image.merge('RGB', (r, g, b))
result.save('result.gif')

# for second row, images 4-6, adjust red and blue channel (1st and 3rd respectively) from darker to lighter

# adjust fourth image, very purple
r, g, b = images[3].split()
r = r.point(lambda i: i * 0.1)
b = b.point(lambda i: i * 0.1)
result = Image.merge('RGB', (r, g, b))
result.save('result.gif')

# adjust fifth image, not quite as purple but still pretty purple 
r, g, b = images[4].split()
r = r.point(lambda i: i * 0.5)
b = b.point(lambda i: i * 0.5)
result = Image.merge('RGB', (r, g, b))
result.save('result.gif')

# adjust sixth image, barely more purple than original
r, g, b = images[5].split()
r = r.point(lambda i: i * 0.9)
b = b.point(lambda i: i * 0.9)
result = Image.merge('RGB', (r, g, b))
result.save('result.gif')

# for third row, images 7-9, start with more red and green for dark yellow and adjust accordingly

# adjust seventh image, very yellow
r, g, b = images[6].split()
r = r.point(lambda i: i * 0.1)
g = g.point(lambda i: i * 0.1)
result = Image.merge('RGB', (r, g, b))
result.save('result.gif')

# adjust eighth image, not quite as yellow but still pretty yellow 
r, g, b = images[7].split()
r = r.point(lambda i: i * 0.5)
g = g.point(lambda i: i * 0.5)
result = Image.merge('RGB', (r, g, b))
result.save('result.gif')

# adjust ninth image, barely more yellow than original
r, g, b = images[8].split()
r = r.point(lambda i: i * 0.9)
g = g.point(lambda i: i * 0.9)
result = Image.merge('RGB', (r, g, b))
result.save('result.gif')

# create a contact sheet from different brightnesses
first_image=images[0]
contact_sheet=PIL.Image.new(first_image.mode, 
(first_image.width*3, first_image.height*3))
x=0
y=0

for img in images:
# Lets paste the current image into the contact sheet
contact_sheet.paste(img, (x, y) )

# Now we update our X position. If it is going to be the width of the image, then we set it to 0 and update Y as well to point to the next "line" of the contact sheet.
if x+first_image.width == contact_sheet.width:
    x=0
    y=y+first_image.height
else:
    x=x+first_image.width

# resize and display the contact sheet
contact_sheet = contact_sheet.resize((int(contact_sheet.width/2),int(contact_sheet.height/2) ))
display(contact_sheet)

I'm sure there is a more efficient way to manipulate my color channels for each image but I haven't found that yet. I think the issue is that the saved version of each image after the color channel change is not being updated in the list of images. I'm not sure what the best way to check for this would be.

Appreciate any feedback!

1

There are 1 best solutions below

1
On

here my attempt at modifiyng your code, I tried with an animated gif:

input: 9frames.gif (its actually 10 frames)

code:

import PIL
from PIL import Image

images = []
imagez= []


img = Image.open('9frames.gif', 'r')

print(img, type(img))

print(img.is_animated)

print(img.n_frames)

for i in range(0, 9): # i.e. range(img.n_frames)
    img.seek(i)
    # img.show()
    images.append(img.convert('RGB'))



# for first row, images 1-3, adjust blue channel (3rd channel) from darker to lighter

# adjust first image, very blue
r, g, b = images[0].split()
b = b.point(lambda i: i * 0.1)
result = Image.merge('RGB', (r, g, b))
imagez.append(result)
        
# adjust second image, not quite as blue but still pretty blue
r, g, b = images[1].split()
b = b.point(lambda i: i * 0.5)
result = Image.merge('RGB', (r, g, b))
imagez.append(result)

# adjust third image, barely more blue than original
r, g, b = images[2].split()
b = b.point(lambda i: i * 0.9)
result = Image.merge('RGB', (r, g, b))
imagez.append(result)

# for second row, images 4-6, adjust red and blue channel (1st and 3rd respectively) from darker to lighter

# adjust fourth image, very purple
r, g, b = images[3].split()
r = r.point(lambda i: i * 0.1)
b = b.point(lambda i: i * 0.1)
result = Image.merge('RGB', (r, g, b))
imagez.append(result)

# adjust fifth image, not quite as purple but still pretty purple 
r, g, b = images[4].split()
r = r.point(lambda i: i * 0.5)
b = b.point(lambda i: i * 0.5)
result = Image.merge('RGB', (r, g, b))
imagez.append(result)

# adjust sixth image, barely more purple than original
r, g, b = images[5].split()
r = r.point(lambda i: i * 0.9)
b = b.point(lambda i: i * 0.9)
result = Image.merge('RGB', (r, g, b))
imagez.append(result)

# for third row, images 7-9, start with more red and green for dark yellow and adjust accordingly

# adjust seventh image, very yellow
r, g, b = images[6].split()
r = r.point(lambda i: i * 0.1)
g = g.point(lambda i: i * 0.1)
result = Image.merge('RGB', (r, g, b))
imagez.append(result)

# adjust eighth image, not quite as yellow but still pretty yellow 
r, g, b = images[7].split()
r = r.point(lambda i: i * 0.5)
g = g.point(lambda i: i * 0.5)
result = Image.merge('RGB', (r, g, b))
imagez.append(result)

# adjust ninth image, barely more yellow than original
r, g, b = images[8].split()
r = r.point(lambda i: i * 0.9)
g = g.point(lambda i: i * 0.9)
result = Image.merge('RGB', (r, g, b))
imagez.append(result)

# create a contact sheet from different brightnesses
first_image=images[0]
contact_sheet=PIL.Image.new(first_image.mode, 
(first_image.width*3, first_image.height*3))
x=0
y=0

for img in imagez:
    # Lets paste the current image into the contact sheet
    contact_sheet.paste(img, (x, y) )

    # Now we update our X position. If it is going to be the width of the image, then we set it to 0 and update Y as well to point to the next "line" of the contact sheet.
    if x+first_image.width == contact_sheet.width:
        x=0
        y=y+first_image.height
    else:
        x=x+first_image.width

# resize and display the contact sheet
contact_sheet = contact_sheet.resize((int(contact_sheet.width/2),int(contact_sheet.height/2) ))
contact_sheet.show()

output:

output.png  (saved by hands)

think you need to play with your channel modifications unless channel order is different in gif and png ... didnt have the input when working on it so I had to use a .gif as per your code

As per others way to modify color-channel, I didnt find a lot, but you colud have a look for another option here:

How to Access and Change Color Channels using PIL?