Is there a way to use ImageGrab on a specific window? (PIL) - python

This code is suppused to take a screenshot of a specific window using ImageGrab(PIL), however the screenshot is not acurrate and I have no Idea why.
here is a screenshot the code took(both not the right size and not in the right position)
and this is the code
import pygetwindow as gw
import PIL.ImageGrab
from pynput.mouse import Button, Controller
mouse = Controller()
from pynput.keyboard import Key, Controller
keyboard = Controller()
chosenWindow = gw.getWindowsWithTitle('Discord')[0]
print(chosenWindow.topleft)
print(chosenWindow.bottomright)
Im = PIL.ImageGrab.grab(bbox=(chosenWindow.topleft[0],chosenWindow.topleft[1],chosenWindow.bottomright[0],chosenWindow.bottomright[1]))
Im.show()

Related

Auto-clicker program doesn't start when key is pressed

so I was trying to make an auto clicker, the other day and for some reason, when I try to activate it with the toggle_key ("t") the program doesn't start. I was following this tutorial https://www.youtube.com/watch?v=4hdK9Gey76E and it seems to work in the video. Can anyone explain why the program doesn't start when I turn it on?
import time
import threading
from pynput.mouse import Controller, Button
from pynput.keyboard import Listener, KeyCode
TOGGLE_KEY = KeyCode(char="t")
clicking = False
mouse = Controller()
def clicker():
while True:
if clicking:
mouse.click(Button.left, 1)
time.sleep(0.001)
def toggle_event(key):
if key == TOGGLE_KEY:
global clicking
clicking = not clicking
click_thread = threading.Thread(target=clicker())
click_thread.start()
with Listener(on_press=toggle_event) as Listener:
Listener.join()

How to press pause key in python

I am creating a pyautogui automation that connect to a W3270 terminal (really old :))
this terminal is expecting pause key to be pressed,
Apart pyautogui, I also tried Keyboard library, but i am unable to send pause
import pyautogui
import keyboard
import constants as const
locateOnScreen(const.IPAIRE_TERMINAL_CONNECTED)
command = '/FOR SIGNON'
pause = '\u0019'
pyautogui.write(command)
time.sleep(1)
keyboard.send('pause')
Am I suppose to use keyboard to simulate 'pause' button?
I found a solution using pynput
import pyautogui
import constants as const
from pynput.keyboard import Key, Controller
locateOnScreen(const.IPAIRE_TERMINAL_CONNECTED)
command = '/FOR SIGNON'
pyautogui.write(command)
time.sleep(1)
keyboard = Controller()
keyboard.press(Key.pause)
keyboard.release(Key.pause)

Custom trigger to execute failsafe in pyautogui

The default trigger of failsafe pyautogui is drag mouse to up-left corner. if i do that then the program will stop. How to change trigger, instead drag mouse i want set the trigger with keyboard input. for example if i press P key then the program will stop (the failsafe executed)
There isnt a way using pyautogui but it has been done using pynput. here is an example (pay attention to def keypress specifiaclly)
from random import random
from threading import Thread
from time import sleep
from pynput.mouse import Controller, Button
from pynput.keyboard import KeyCode, Listener
import pyautogui
delay = float(pyautogui.confirm(text='Choose Clicking Speed Per Second', title='Spook AutoClicker', buttons=['0.5','0.001']))
mouse = Controller()
class AutoClicker(Thread):
clicking = False
def run(self):
while True:
if AutoClicker.clicking:
mouse.click(Button.left)
sleep(delay)
def keypress(key):
if key == KeyCode(char="p"):
AutoClicker.clicking = not AutoClicker.clicking
AutoClicker().start()
with Listener(on_press=keypress) as listener:
listener.join()

How to get the screenshot of a tkinter window

I am trying to build a program which gets me an enlarged photo of the text I want, for this I decided to use tkinter, win32gui and pygetwindow modules after taking some tips from already asked problems on stack overflow am having the following problems:
(1)I don't know how to get the hwnd value of the tkinter window which I created.
(2)I can't get hwnd value even if I know how to get it as the window is created after the complete code has run.
So please suggest me solutions to the problem
This is my code:
from tkinter import *
import win32gui
import pygetwindow as gw
#making the tkinter window
root = Tk()
root.title('DaysLeft')
#getting all the windows with their hwnd values
hwnd=gw.getAllWindows()
print(hwnd)
win32gui.SetForegroundWindow(hwnd)
bbox = win32gui.GetWindowRect(hwnd)
img = ImageGrab.grab(bbox)
img.show()
mainloop()
The above code gives error below as expected:.
line 26, in <module>
win32gui.SetForegroundWindow(hwnd)
TypeError: The object is not a PyHANDLE object
You can use PIL for taking a screenshot and win32gui or pygetwindow to get windows location.
Install PIL by saying
pip install Pillow
then your working code would be:
from tkinter import *
from win32gui import FindWindow, GetWindowRect
import pygetwindow as gw
from PIL import ImageGrab
def ss():
win = gw.getWindowsWithTitle('DaysLeft')[0]
winleft = win.left+9
wintop = win.top+38 #change 38 to 7 to not capture the titlebar
winright = win.right-9
winbottom = win.bottom-9
final_rect = (winleft,wintop,winright,winbottom)
img = ImageGrab.grab(final_rect)
img.save('Required Image.png')
#making the tkinter window
root = Tk()
root.title('DaysLeft')
root.after(3000,ss)
root.mainloop()
Why am i subtracting some amount from the pixels? its because, windows has decorations like drop shadow effect to the windows, which are also part of the windows and will be included in the screenshot, so i used this to get rid of those extra pixels.
Or if your still reluctant on using win32gui then, change the function to:
from win32gui import FindWindow, GetWindowRect
from PIL import ImageGrab
......
def ss():
win = FindWindow(None, 'DaysLeft')
rect = GetWindowRect(win)
list_rect = list(rect)
list_frame = [-9, -38, 9, 9] #change -38 to -7 to not capture the titlebar
final_rect = tuple((map(lambda x,y:x-y,list_rect,list_frame))) #subtracting two lists
img = ImageGrab.grab(bbox=final_rect)
img.save('Image.png')
What is after method? It just calls the function after 3000 ms, i.e, 3 seconds. We are basically giving the system some time to build the GUI and capture screenshot.
Hope it helped, do let me know if any errors or doubts.
Cheers

Pynput while not using text field

Im trying to make a simple code to crouch when I run it. this is my code:
from pynput.keyboard import Key, Controller
import time
import keyboard as key
keyboard = Controller()
time.sleep(2)
for i in range(30):
keyboard.press("c")
keyboard.release('c')
time.sleep(0.1)

Categories

Resources