I have two images and would like to extract multiple areas from the first image and overlay them on the second image. Is there a way to crop multiple areas from an image without loading the first image in again with Python Wand? Something like the opposite of +repage in ImageMagick.
bg_img = Image(filename = 'second_image.jpg')
fg_img = Image(filename = 'first_image.jpg')
left = 50
top = 600
width = 30
height = 30
fg_img.crop(left, top, width=width, height=height)
bg_img.composite(fg_img, left, top)
fg_img = Image(filename = 'first_image.jpg')
left = 500
top = 600
width = 100
height = 30
fg_img.crop(left, top, width=width, height=height)
bg_img.composite(fg_img, left, top)
bg_img.save(filename='second_image_plus_overlays.png')
You can do that in Python Wand by cloning the input.
Input:
from wand.image import Image
from wand.display import display
with Image(filename='lena.jpg') as img:
with img.clone() as copy1:
copy1.crop(left=50, top=100, width=100, height=50)
copy1.save(filename='lena_crop1.jpg')
display(copy1)
with img.clone() as copy2:
copy2.crop(left=100, top=50, width=50, height=100)
copy2.save(filename='lena_crop2.jpg')
display(copy2)
Result 1:
Result 2:
Related
I want to put this image on the canvas, only without borders, or with the border of the canvas color. I already put border size = 0 but it didn't work.
What do I do please?
image1 = Image.open("imagem2.png")
image = image1.resize((120, 120), Image.ANTIALIAS)
test = ImageTk.PhotoImage(image)
label1 = ttk.Label(image=test, borderwidth=0)
label1.image = test
# Position image
label1.place(x=0, y=230)
I would like to take these edges
I'm trying to put an image inside the Canvas that has the same width as the Canvas but the height is according to the aspect ratio, and using a Scrollbar to scroll the same. Here's the relevant part of the code.
#Canvas and Scrollbar
img_canvas = Canvas(main_frame, height = height, width = width+15)
vsb = Scrollbar(img_canvas, orient = 'vertical')
vsb.pack(side = 'right', fill = 'y')
vsb.configure(command = img_canvas.yview)
canvas.config(yscrollcommand = vsb.set)
text.window_create("end", window = img_canvas)
text.insert("end", "\n")
#Insert Image into the Canvas
im = Image.open(str(opath)+"//Ques_"+str(temp)+".png")
w, h = im.size
im = im.resize((width, int((h/w)*width)), Image.ANTIALIAS)
img = ImageTk.PhotoImage(im)
ques = Label(img_canvas, image = img)
ques.image = img
ques.pack(side = 'left', expand = False)
The problem I am encountering is that the image expands completely in y, and hence can't be scrolled.
I want to contain the part of the image that fits into the Canvas's dimensions and the rest can be scrolled.
You have to use create_image to put an image on a canvas and have it be scrollable. You can't use pack or place or grid. You don't need to put the image in a label first, unless you specifically want it to be a label with a border. In that case, you need to use create_window to add the label to the canvas.
I'm using tkinter and I have a "sprite sheet" and I want to cut it into multiple images. I tried PIL:
img = Image.open("test.png").convert("RGBA")
img2 = img.crop([300,300,350,350])
image = ImageTk.PhotoImage(img2)
win = tk.Tk()
label = tk.Label(win, image = image)
label.pack()
but on my window, there is only an empty white rectangle and I don't understand why. Moreover I tried img2.show() just to make shure that img2 wasn't empty and it wasn't.
Here is your code, with a few changes. Note the call to Tk() at the top, and mainloop() at the bottom. The other modification is that it obtains the width and height of the image and then crops 25% from each of the four sides to leave the middle 50% of the image.
#!/usr/bin/python
from tkinter import *
from PIL import ImageTk,Image
root = Tk()
img = Image.open("test.png").convert("RGBA")
w, h = img.size
left = w/4
right = 3*w/4
upper = h/4
lower = 3*h/4
img2 = img.crop([ left, upper, right, lower])
image = ImageTk.PhotoImage(img2)
label = Label(root, image = image)
label.pack()
root.mainloop()
I have the following piece of code:
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk
import cv2
import os
import glob
import numpy as np
image_path = ""
image_list = []
class Proj:
def __init__(self, master):
self.master = master
#GUI height and width
w = 1250
h = 600
# open folder manager to select image folder
image_path = filedialog.askdirectory()
master.geometry("%dx%d%+d%+d" % (w ,h ,0,0))
master.resizable(True,True)
#read in images from folder
self.read_images(master, image_path)
#cv2.imshow('image',cv2.imread(image_list[0], 1))
self.img = cv2.imread(image_list[0])
self.img = Image.fromarray(np.array(self.img).copy())
self.img.thumbnail((w//2, w//2+10))
self.img = ImageTk.PhotoImage(self.img)
image_frame = Frame(master)
image_frame.grid(row = 0, column = 0, columnspan = 3, rowspan = 5)
left_panel = Canvas(image_frame, width=w//2, height=h-70)
left_panel.grid(row=0, column=0, columnspan=4)
imgA_handler = left_panel.create_image((0,0), image = self.img, anchor="nw")
right_panel = Canvas(image_frame, width=w//2, height=h-70)
right_panel.grid(row=0, column=5, columnspan=4)
def read_images(self, master, path):
images = path + '/*.tif'
for img in glob.glob(images): #will only read in tif images
image_list.append(img)
root = Tk()
example = Proj(root)
root.mainloop()
I am reading in color .tif images and then trying to display them in the left_panel. However, when I go to do that, it shows the normal color image only in red scale even though I never extracted just the red signal. I am completely unable to diagnose the issue. How do I fix this issue?
Ultimately, what I want to do is display two images on this GUI. An original image on the left and a modified image on the right. Currently my gui layout is set up as I've coded above. However, if you think there is an easier way to do this, then I'd be interested to hear.
This is because opencv uses BGR instead of RGB. When you are using this line: self.img = Image.fromarray(np.array(self.img).copy()) Blue and Red colors are being swapped. Just before you use the above code, convert the BGR to RGB in opencv and you should be good to go.
self.img = cv2.cvtColor(self.img,cv2.COLOR_BGR2RGB)
I see you are using opencv. Why don't you use the opencv command to resize.
It is very simple and works pretty well.
Take a look at this page:
OpenCV Resize
This is an example to make a image 50% smaller, or instead of the fx and fy, you can put the exact size you want.
thumbnail = cv2.resize(image, (0,0), fx=0.5, fy=0.5)
I want to show an image and draw a coordinate system(x-axe, y-axe) on top of it.
I can show the image
img = ImageTk.PhotoImage(Image.open(path).resize((400,400),Image.ANTIALIAS))
panel = tk.Label(root,image = img, width = 400, height = 400s)
panel.pack(size= "bottom", fill = "both", expand = "yes")
panel.place(rely = 073, rely = 0.5s)
I can also draw a line for the x-axe/y-axe(it would be even better if you know a way to draw a flash instead of a line)
canvas = Canvas(root)
canvas.create_line(x0,y0,x1,y1)
canvas.pack()
What I cannot do is place this line on top of the image. I tried using canvas.place(), but when I put it on top of the image I cannot see the image anymore. Is there a way to make the canvas transparent ? Or is there something else I can do ? I'm new to Tkinter.
Thanks.
EDIT: apparently it is not possible to make a canvas transparent Transparent canvas in tkinter python
But can I add a background image in the canvas and then draw the line, so that I can see both ?
You have to place the image on the canvas and then put the axis lines on top of it:
import Tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
img_path = 'water-drop-splash.png'
img = ImageTk.PhotoImage(Image.open(img_path).resize((400,400), Image.ANTIALIAS))
canvas = tk.Canvas(root, height=400, width=400)
canvas.create_image(200, 200, image=img)
canvas.create_line(0, 200, 399, 200, dash=(2,2)) # x-axis
canvas.create_line(200, 0, 200, 399, dash=(2,2)) # y-axis
canvas.pack()
root.mainloop()
Ta-da!