Take a screenshot in Python

Created because I was able to pass a part of the desktop image to another program with python.

environment

Windows10

Movement

  1. Save and view desktop images
  2. Drag and drop to select a range
  3. Cut out and save the selected part

code

python_screenshot.pyw


import datetime
import os
from ctypes import windll
from PIL import Image, ImageGrab
import tkinter as tk

class CropScreenShot(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.flag = False
        current_dir = os.path.split(os.path.abspath(__file__))[0]
        self.ss_folder = os.path.join(current_dir,'crop_screen_shot_temp')
        os.makedirs(self.ss_folder, exist_ok=True)
        
        self.make_ss()
        root.minsize(self.screen_width, self.screen_height)
        self.image = tk.PhotoImage(file=self.ss_file_path)
        self.draw_ss(self.image,self.screen_width, self.screen_height)
        
    def make_ss(self):
        self.screen_width = windll.user32.GetSystemMetrics(0)
        self.screen_height = windll.user32.GetSystemMetrics(1)

        dt_now = datetime.datetime.now()
        ss_name = 'ss_{}.png'.format(dt_now.strftime('%Y%m%d_%H%M%S'))
        self.ss_file_path = os.path.join(self.ss_folder, ss_name)

        screen_shot = ImageGrab.grab().resize((self.screen_width, self.screen_height))
        screen_shot.save(self.ss_file_path)
    
    def draw_ss(self,image,width,height):
        self.canvas = tk.Canvas(bg='black', width=width, height=height)
        self.canvas.place(x=0, y=0)
        self.canvas.create_image(0, 0, image=image, anchor=tk.NW)

        self.left_x = tk.IntVar(value=0)
        self.upper_y = tk.IntVar(value=0)
        self.right_x = tk.IntVar(value=width+1)
        self.lower_y = tk.IntVar(value=height+1)

        self.canvas.bind('<ButtonPress-1>',self.light_click_down)
        self.canvas.bind('<B1-Motion>',self.light_click_drag)
        self.canvas.bind('<ButtonRelease-1>',self.light_click_up)

    def crop_ss(self,left_x,upper_y,right_x,lower_y):
        pil_image = Image.open(self.ss_file_path)
        dt_now = datetime.datetime.now()
        crop_ss_name = 'crop_{}.png'.format(dt_now.strftime('%Y%m%d_%H%M%S'))
        crop_file_path = os.path.join(self.ss_folder, crop_ss_name)
        trim_image = pil_image.crop((left_x,upper_y,right_x,lower_y))
        new_width = right_x - left_x
        new_height = lower_y - upper_y
        new_image = Image.new(trim_image.mode, (new_width, new_height),'white')
        new_image.paste(trim_image, (0,0))
        new_image.save(crop_file_path)

    def delete_rectangle(self,tag):
        objs = self.canvas.find_withtag(tag)
        for obj in objs:
            self.canvas.delete(obj)

    def draw_rectangle(self,left_x,upper_y,right_x,lower_y):
        self.canvas.create_rectangle(
            left_x,
            upper_y,
            right_x,
            lower_y,
            outline='blue',
            width=2,
            tag='crop_area'
            )        

    def light_click_down(self,event):
        if self.flag == False:
            self.delete_rectangle(tag='crop_area')
            self.left_x.set(event.x)
            self.upper_y.set(event.y)
            self.right_x.set(event.x)
            self.lower_y.set(event.y)
            self.draw_rectangle(
                self.left_x.get(),
                self.upper_y.get(),
                self.right_x.get(),
                self.lower_y.get()
                )
            
    def light_click_drag(self,event):
        if self.flag == False:
            self.delete_rectangle(tag='crop_area')
            self.right_x.set(event.x)
            self.lower_y.set(event.y)
            if self.left_x.get() > self.right_x.get():
                if self.upper_y.get() > self.lower_y.get():
                    self.draw_rectangle(
                        self.right_x.get(),
                        self.lower_y.get(),
                        self.left_x.get(),
                        self.upper_y.get(),
                        )
                else:
                    self.draw_rectangle(
                        self.right_x.get(),
                        self.upper_y.get(),
                        self.left_x.get(),
                        self.lower_y.get(),
                        )
            else:
                if self.upper_y.get() > self.lower_y.get():
                    self.draw_rectangle(
                        self.left_x.get(),
                        self.lower_y.get(),
                        self.right_x.get(),
                        self.upper_y.get(),
                        )
                else:
                    self.draw_rectangle(
                        self.left_x.get(),
                        self.upper_y.get(),
                        self.right_x.get(),
                        self.lower_y.get(),
                        )
                
    def light_click_up(self,event):
        if self.flag == False:
            self.flag = True
            self.delete_rectangle(tag='crop_area')
            self.right_x.set(event.x)
            self.lower_y.set(event.y)
            if self.left_x.get() > self.right_x.get():
                if self.upper_y.get() > self.lower_y.get():
                    self.draw_rectangle(
                        self.right_x.get(),
                        self.lower_y.get(),
                        self.left_x.get(),
                        self.upper_y.get(),
                        )
                    self.crop_ss(
                        self.right_x.get(),
                        self.lower_y.get(),
                        self.left_x.get(),
                        self.upper_y.get(),
                        )
                else:
                    self.draw_rectangle(
                        self.right_x.get(),
                        self.upper_y.get(),
                        self.left_x.get(),
                        self.lower_y.get(),
                        )
                    self.crop_ss(
                        self.right_x.get(),
                        self.upper_y.get(),
                        self.left_x.get(),
                        self.lower_y.get(),
                        )
            else:
                if self.upper_y.get() > self.lower_y.get():
                    self.draw_rectangle(
                        self.left_x.get(),
                        self.lower_y.get(),
                        self.right_x.get(),
                        self.upper_y.get(),
                        )
                    self.crop_ss(
                        self.left_x.get(),
                        self.lower_y.get(),
                        self.right_x.get(),
                        self.upper_y.get(),
                        )
                else:
                    self.draw_rectangle(
                        self.left_x.get(),
                        self.upper_y.get(),
                        self.right_x.get(),
                        self.lower_y.get(),
                        )
                    self.crop_ss(
                        self.left_x.get(),
                        self.upper_y.get(),
                        self.right_x.get(),
                        self.lower_y.get(),
                        )
            root.destroy()
            

root = tk.Tk()
app = CropScreenShot(master=root)

app.mainloop()

reference

Thank you to our ancestors. Described as far as I can remember. https://qiita.com/koara-local/items/6a98298d793f22cf2e36 https://note.nkmk.me/python-pillow-image-crop-trimming/ https://daeudaeu.com/programming/python/tkinter/trimming_appli/ https://betashort-lab.com/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0/python/tkinter%E3%81%A7%E7%94%BB%E5%83%8F%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%95%E3%81%9B%E3%82%8B%E6%96%B9%E6%B3%95/

Recommended Posts

Take a screenshot in Python
[Python] Take a screenshot
[Python] [Windows] Take a screen capture in Python
Create a function in Python
Create a dictionary in Python
Make a bookmarklet in Python
Draw a heart in Python
Maybe in a python (original title: Maybe in Python)
Write a binary search in Python
[python] Manage functions in a list
Hit a command in Python (Windows)
Create a DI Container in Python
Draw a scatterplot matrix in python
ABC166 in Python A ~ C problem
Write A * (A-star) algorithm in Python
Create a binary file in Python
Solve ABC036 A ~ C in Python
Write a pie chart in Python
Write a vim plugin in Python
Write a depth-first search in Python
Implementing a simple algorithm in Python 2
Create a Kubernetes Operator in Python
Solve ABC037 A ~ C in Python
Run a simple algorithm in Python
Draw a CNN diagram in Python
Create a random string in Python
Schedule a Zoom meeting in Python
When writing a program in Python
Python in optimization
CURL in python
Metaprogramming in Python
Spiral book in Python! Python with a spiral book! (Chapter 14 ~)
Solve ABC175 A, B, C in Python
Python 3.3 in Anaconda
Geocoding in python
SendKeys in Python
Use print in a Python2 lambda expression
A simple HTTP client implemented in Python
Do a non-recursive Euler Tour in Python
Meta-analysis in Python
I made a payroll program in Python!
Precautions when pickling a function in python
Unittest in python
Write the test in a python docstring
Display a list of alphabets in Python 3
Try sending a SYN packet in Python
Try drawing a simple animation in Python
Create a simple GUI app in Python
Create a JSON object mapper in Python
Epoch in Python
Discord in Python
Write a short property definition in Python
Draw a heart in Python Part 2 (SymPy)
Sudoku in Python
DCI in Python
quicksort in python
nCr in python
Run the Python interpreter in a script
N-Gram in Python
How to get a stacktrace in python
Programming in python