Python - image watermark - python-3.x

my goal is to create a watermark image, based on a logo (TIF format) and a background image (JPG).
I'm using this code:
from PIL import Image
def watermark_with_transparency(input_image_path,
output_image_path,
watermark_image_path,
position):
base_image = Image.open(input_image_path)
watermark = Image.open(watermark_image_path)
width, height = base_image.size
transparent = Image.new('RGBA', (width, height), (0,0,0,0))
transparent.paste(base_image, (0,0))
transparent.paste(watermark, position, mask=watermark)
transparent.show()
transparent.save(output_image_path)
Watermark image is a trasparent TIF.
If I run above code, watermark result does not include any logo.
What I'm doing wrong?

from PIL import Image,ImageDraw, ImageFont
path=r'/home/anuj/FIle_server/production/AI_PROJECT/SEQ_001/sq1/frm_seq_v001.001.jpeg' #This is path of your image
demo_image = Image.open(path)
img_width, img_height =demo_image.size
draw_image = ImageDraw.Draw(demo_image)
text_image ="HQVFX" #Here you can assign your watermark.
font_image =ImageFont.truetype('/home/anuj/FIle_server/task/WaterBrush-Regular.ttf',50)
text_width, text_height = draw_image.textsize(text_image,font_image)
font_margin = 10
x = img_width - text_width - font_margin
y = img_height - text_height - font_margin
draw_image.text((x,y), text_image, font= font_image)
demo_image.show()
demo_image.save("watermark.jpg")

Related

Adding a border around Region of Interest using python

I have a code which takes images from a folder, crops the region of interest around it using the ROI function, and then removes the background using the rembg library. But I want a border around that image, around that specific object itself, like the one we get in segmentation, except keeping the colours and the object intact. [NOT A RECTANGULAR BORDER]. Can anyone help and tell me how to do it?
Here is my code for reference:
import cv2
import numpy as np
import os
from os.path import join
from os import listdir
from PIL import Image
from rembg import remove
path = 'Some path'
folder = 'Some other path'
count = 1
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
if width is None and height is None:
return image
if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation = inter)
return resized
for filename in os.listdir(folder):
img = cv2.imread(os.path.join(folder,filename))
if img is not None:
img = image_resize(img, height = 600)
roi = cv2.selectROI(img)
print(roi)
im_cropped = img[int(roi[1]):int(roi[1]+roi[3]),int(roi[0]):int(roi[0]+roi[2])]
rs = str(count)
rem = remove(im_cropped)
cv2.imshow("Removed Image", rem)
cv2.imwrite(os.path.join(path, rs + '.jpg'), rem)
count = count + 1
cv2.waitKey(0)
As i assume you mean a simple outline, i would suggest the following:
import cv2
import numpy as np
# Threshold the image
thresh = img > threshold
# Use binary dilation to widen the area
thresh_dil = cv2.dilate(thresh, np.ones((3, 3)) , iterations=1)
# Get the outlines by substracting the dilated image with the original area
outlines = thresh_dil - thresh
# Superimpose the outlines on your original image
img_with_outlines = img.copy()
img_with_outlines[outlines > 0] = 255
This should draw a white line around your detected object.
Note: This approach works grayscale images. For full colour images you can apply it for each channel individually.

How can I resize image without stretching it in Tkinter?

I am currently working on a project which requires displaying Images of different sizes. So I wanted to use tkinter for that purpose.
Here is my Code for displaying image
from tkinter import Tk, Label
from PIL import Image, ImageTk
root = Tk()
root.title("Display Images")
root.geometry('550x550')
root.maxsize(550, 550)
root.iconbitmap('icon.ico')
root.configure(background='#333')
image = Image.open('./image.jpg')
resized_image = image.resize((540, 540), Image.ANTIALIAS)
disp_image = ImageTk.PhotoImage(resized_image)
label = Label(image=disp_image) #.pack(padx=10, pady=10)
label.configure(border=0)
label.pack(padx=10, pady=10)
root.mainloop()
which works perfectly fine but
I wanted to display different sizes of images without stretching them.
Like, If image size exceeds the window size, it should take the size of the window, and If image size is less than the size of the window then there should be no change in image size.
Example:
I have two images of width and height [200x300, 400x500]
and my display size(windows width and height) is 350x350
When I display an image of size 200x300, it should display as it is without change in size and when I display another image it should change its size to 350x350
So, is there a way to pull that off?
Here is a solution:
from tkinter import Tk, Label
from PIL import Image, ImageTk
root = Tk()
root.title("Display Images")
root.geometry('550x550')
root.maxsize(550, 550)
root.configure(background='#333')
image = Image.open('./image.jpg')
# main part -----------------------------------------
if image.width > 540 and image.height > 540:
resized_image = image.resize((540, 540), Image.ANTIALIAS)
elif image.width > 540:
resized_image = image.resize((540, image.height), Image.ANTIALIAS)
elif image.height > 540:
resized_image = image.resize((image.width, 540), Image.ANTIALIAS)
else:
resized_image = image
# end main part ----------------------------------------
disp_image = ImageTk.PhotoImage(resized_image)
label = Label(image=disp_image, border=0)
label.pack(padx=10, pady=10)
root.mainloop()
Simple use of if statements.

How to convert ImageTk to Image?

Let's say I have some ImageTk.PhotoImage image stored in the variable imgtk. How can I convert it back to an Image.Image?
The reason is that I want to resize it, but it seems that .resize() only works for Image.Images.
I know it is awfully late, but I just came across the same issue and I just discovered that there is a getimage(imagetk) function in the ImageTk interface.
So, to get your imgtk back as an PIL Image you can do:
img = ImageTk.getimage( imgtk )
I just did a quick test on Windows (Python 3.8.5/Pillow 8.1.2/Tkinter 8.6) and it seems to work fine:
# imgtk is an ImageTk.PhotoImage object
img = ImageTk.getimage( imgtk )
img.show()
img.close()
Ok, that was not easy but I think I have a solution though you need to go into some private methods of label.image. Maybe there is a better way if so I would love to see.
import tkinter as tk
from tkinter import Label
import numpy as np
from PIL import Image, ImageTk
root = tk.Tk()
# create label1 with an image
image = Image.open('pic1.jpg')
image = image.resize((500, 750), Image.ANTIALIAS)
picture = ImageTk.PhotoImage(image=image)
label1 = Label(root, image=picture)
label1.image = picture
# extract rgb from image of label1
width, height = label1.image._PhotoImage__size
rgb = np.empty((height, width, 3))
for j in range(height):
for i in range(width):
rgb[j, i, :] = label1.image._PhotoImage__photo.get(x=i, y=j)
# create new image from rgb, resize and use for label2
new_image = Image.fromarray(rgb.astype('uint8'))
new_image = new_image.resize((250, 300), Image.ANTIALIAS)
picture2 = ImageTk.PhotoImage(image=new_image)
label2 = Label(root, image=picture2)
label2.image = picture2
# grid the two labels
label1.grid(row=0, column=0)
label2.grid(row=0, column=1)
root.mainloop()
Actually you can zoom and reduce the original picture by using the methods zoom to enlarge the picture (zoom(2) doubles the size) and subsample to reduce the size (subsample(2) halves the picture size).
for example
picture2 = label1.image._PhotoImage__photo.subsample(4)
reduces the size of the picture to a quarter and you can skip all the conversion to an Image.
According to label1.image._PhotoImage__photo.subsample.__doc__:
Return a new PhotoImage based on the same image as this widget but use only every Xth or Yth pixel. If y is not given, the default value is the same as x
and label1.image._PhotoImage__photo.zoom.__doc__:
Return a new PhotoImage with the same image as this widget but zoom it with a factor of x in the X direction and y in the Y direction. If y is not given, the default value is the same as x.

size of a background image in tkinter

I need to resize my window(tkinter) according to the width and height of my background image.
My code
from tkinter import *
from PIL import ImageTk
import cv2
image=cv2.imread("New_refImg.png")
width_1, height_1,channels = image.shape
canvas = Canvas(width = width_1, height = height_1, bg = 'blue')
canvas.pack(expand = YES, fill = BOTH)
img = ImageTk.PhotoImage(file = "New_refImg.png")
canvas.create_image(10, 10, image = img, anchor = NW)
mainloop()
I'm using a simple method, I call the same image twice : image=cv2.imread("New_refImg.png") and img = ImageTk.PhotoImage(file = "New_refImg.png") but is there a way change this line img = ImageTk.PhotoImage(file = "New_refImg.png") to something like that img = ImageTk.PhotoImage(image) (image already has been called in the 3rd line of the code)
Thank you
I don't know about PIL, but I can show you how to do it in tkinter:
from tkinter import *
root = Tk() # Create Tk before you can create an image
img = PhotoImage(file='pilner.png')
w, h = img.width(), img.height()
canvas = Canvas(root, width=w, height=h, bg='blue', highlightthickness=0)
canvas.pack(expand = YES, fill = BOTH)
canvas.create_image(0, 0, image=img, anchor=NW)
root.mainloop()
highlightthickness=0 rmoves the highlight border on the canvas. I'm positioning it at 0,0 so as to not show the bg.

PNG image that support scaling and changing transparency in python

I want to show PNG picture on canvas.
Before it I need to resize it and change transparency.
I found that I can load image and change alpha channel with PhotoImage like this:
image1 = PIL.Image.open('aqua.png')
image1.putalpha(128)
gif1 = ImageTk.PhotoImage(image1)
Also I can load PhotoImage and resize it like this:
gif1 = PhotoImage(file = 'aqua.png')
gif1 = gif1.subsample(5)
But I can't perform both this things on same PhotoImage
I understand that PhotoImage and ImageTk.PhotoImage are different classes in my code.
>> print (ImageTk.PhotoImage)
<class 'PIL.ImageTk.PhotoImage'>
>> print (PhotoImage)
<class 'tkinter.PhotoImage'>
I tried to found functionality that I need in both classes but without success.
Maybe I need perform subsample and than convert my tkinter.PhotoImage to PIL.ImageTk.PhotoImage and then perform putalpha but it sounds weird.
Please refer me to right direction about png cooking in Python.
Here is all my code:
from tkinter import *
import PIL
from PIL import Image, ImageTk
canvas = Canvas(width = 200, height = 200)
canvas.pack(expand = YES, fill = BOTH)
image1 = PIL.Image.open('aqua.png')
image1.putalpha(128)
gif1 = ImageTk.PhotoImage(image1)
# gif1 = PhotoImage(file = 'aqua.png')
# next line will not work in my case
gif1 = gif1.subsample(5)
canvas.create_image(0, 0, image = gif1, anchor = NW)
mainloop()
You can use the resize method included in the Image class. Here is the modified code:
from tkinter import *
from PIL import Image, ImageTk
canvas = Canvas(width = 200, height = 200)
canvas.pack(expand = YES, fill = BOTH)
image1 = Image.open('aqua.png')
image1.putalpha(128)
image1 = image1.resize((image1.width//5,image1.height//5))
gif1 = ImageTk.PhotoImage(image1)
canvas.create_image(0, 0, image = gif1, anchor = NW)
mainloop()

Resources