Python version 3.10 generating a error when trying to add a watermark to an image

Note: all 3.9 versions run the code perfectly creating the watermarked image.

I created this project to fit a watermark cross that perfectly fits the size of the image, but in this line of code:

paste_mask = watermark.split()[3].point(lambda i: i * TRANSPARENCY / 100.)

It generating this error:

File "c:\Users\Computador\Desktop\Python\Watermark.py", line 29, in watermark_with_transparency
paste_mask = watermark.split()[3].point(lambda i: i * TRANSPARENCY / 100.)
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\PIL\Image.py", line 1723, in point
return self._new(self.im.point(lut, mode))
TypeError: 'float' object cannot be interpreted as an integer

The complete code is:

from PIL import Image

def watermark_with_transparency(input_image_path,
                                output_image_path,
                                watermark_image_path):
    TRANSPARENCY = 10
    angle = 30
    base_image = Image.open(input_image_path)
    w_img, h_img = base_image.size
    basewidth = w_img
    watermark = Image.open(watermark_image_path)
    watermark = watermark.rotate(angle, expand=True)
    wpercent = (basewidth / float(watermark.size[0]))
    hpercent = h_img / float(watermark.size[1])
    if wpercent < hpercent:
        hsize = int((float(watermark.size[1]) * float(wpercent)))
        watermark = watermark.resize((basewidth, hsize), Image.ANTIALIAS)
    else:
        wsize = int((float(watermark.size[0]) * float(hpercent)))
        watermark = watermark.resize((wsize, h_img), Image.ANTIALIAS)
    w_logo, h_logo = watermark.size
    center_y = int(h_img / 2)
    center_x = int(w_img / 2)
    top_y = center_y - int(h_logo / 2)
    left_x = center_x - int(w_logo / 2)
    if watermark.mode != 'RGBA':
        alpha = Image.new('L', (w_img, h_img), 255)
        watermark.putalpha(alpha)
    paste_mask = watermark.split()[3].point(lambda i: i * TRANSPARENCY / 100.)
    base_image.paste(watermark, (left_x, top_y), mask=paste_mask)
    base_image.save(output_image_path)

The model in the image is ok and the values in my view are correct, what should i modify to work in this new python version?

Bit of an old topic, but I am seeing this:

def point(self, lut, mode=None):
        """
        :param mode: Output mode (default is same as input).  In the
           current version, this can only be used if the source image
           has mode "L" or "P", and the output has mode "1" or the
           source image mode is "I" and the output mode is "L".
        """
        if self.mode == "F":
            # FIXME: _imaging returns a confusing error message for this case
            msg = "point operation not supported for this mode"
            raise ValueError(msg)

        if mode != "F":
            lut = [round(i) for i in lut]

so it looks like there are two conflicting checks, where the first throws an error if it’s in “F” mode, and the second checks if it’s not in “F” mode and converts the LUT to integers. So maybe you just have to add a conversion to int in the lambda.

You can use Cloudinary’s Python libraries to watermark your images.