Error: can't multiply sequence by non-int of type 'float'

Question:

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?

Asked By: Sinkos

||

Answers:

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)
Answered By: Gameplay

🙂

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)
Answered By: Sinkos
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.