I am trying to create a project where it is necessary to implement a fade image transition between two images. But i got error: can't multiply sequence by non-int of type 'float'
Here is my code:
import tkinter as tk
from PIL import ImageTk, Image
root = tk.Tk()
root.geometry('300x300')
root.resizable(width = True, height = True)
image1 = Image.open('name.jpg')
image2 = Image.open('name.png')
width = min(image1.width, image2.width)
height = min(image1.height, image2.height)
image1 = image1.resize((width, height),Image.ANTIALIAS)
image2 = image2.resize((width, height),Image.ANTIALIAS)
def ob_Fade(image1, image2, d):
new_image = Image.new('RGB', (image1.width, image1.height), color='white')
for x in range(image1.width):
for y in range(image1.height):
pixel_1 = image1.getpixel((x, y))
pixel_2 = image2.getpixel((x, y))
new_image.putpixel((x, y), (d * pixel_1 (1 - d) * pixel_2))
return new_image
def start():
for i in range(0,100, 1):
d = i/100
image = ob_Fade(image1, image2, d)
image = image.resize((250, 250),Image.ANTIALIAS)
image = ImageTk.PhotoImage(image)
image_label = tk.Label(root, image = image)
image_label.image = image
image_label.grid(row = 2, column = 1)
root.update()
done = tk.Button(root, text="DO", padx=1, pady=0, command=start)
done.grid(row = 0, column = 1)
root.mainloop()
But I can't fix it with int(d)
, because if d is 0 then image 1 is copied, if d is 1 then image 2 is copied, this means that the transition will not happen at all.
Maybe someone could help?
CodePudding user response:
This line returns a tuple:
pixel_1 = image1.getpixel((x, y))
e.g. pixel_1 is (2,3,4)
, that's why you cannot multiply a tuple by float and
that's more or less what you are doing (example):
7.89*(2,3,4)
You have to iterate through the tuple and multiply in a loop/comprehension and then convert it back to a tuple (for a single pixel that would be):
tuple([int(d*channel) for channel in pixel_1])
In your case you need to iterate simultaneously over both pixels (or their channels to be exact) and calculate new pixel value based on both of them, taking d
multiplied by channels from the 1st one and 1-d
multiplied by the channels from the 2nd one:
new_pixel_values = tuple([int(d*c1 (1-d)*c2) for c1, c2 in zip(pixel_1, pixel_2)])
new_image.putpixel((x, y), new_pixel_values)
CodePudding user response:
:)
new_red = gala * pixel_1[0] (1 - gala) * pixel_2[0]
new_green = gala * pixel_1[1] (1 - gala) * pixel_2[1]
new_blue = gala * pixel_1[2] (1 - gala) * pixel_2[2]
new_pixel = (int(new_red), int(new_green), int(new_blue))
new_image.putpixel((x, y), new_pixel)