0

I am attempting to take a screenshot of my desktop across multiple monitors using pywin32.

I have the screenshot I need on my third monitor but I only need a certain region of the image.

I am able to crop it when I save the bitmapped image to my hard drive like so:

# initial set up code hooking up pywin32 to the desktop

import win32gui, win32ui, win32con, win32api
hwin = win32gui.GetDesktopWindow()

# example dimensions
width = 800
height = 600
left = 3300
top = 100

hwindc = win32gui.GetWindowDC(hwin)
srcdc = win32ui.CreateDCFromHandle(hwindc)
memdc = srcdc.CreateCompatibleDC()
bmp = win32ui.CreateBitmap()
bmp.CreateCompatibleBitmap(srcdc, width, height)
memdc.SelectObject(bmp)

# saving of the file (what I am currently doing)
bmp.SaveBitmapFile(memdc, 'fullshot.bmp')

# strangely enough this crops the portion I need, 
# but within an image that's the entire length of my desktop
# (not sure how to fix that, you could say this is part of the problem)
memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY)


img = Image.open('fullshot.bmp')
img = img.crop((0,0,800,600))
# now the cropped image is in memory but I want just the portion I need without saving it to disk

The bmp is of type 'PyCBitmap'. I've tried np.array(bmp) but this doesn't work either. Is there a way can take the bmp screenshotted by pwin32 and crop it to the dimensions I need within the program memory?

update:

I tried the following code which does not work either. When I try to display it with cv2.imshow('image', img) I get an unresponsive window.

signedIntsArray = bmp.GetBitmapBits(True)
img = np.frombuffer(signedIntsArray, dtype='uint8')
img.shape = (height,width,4)

srcdc.DeleteDC()
memdc.DeleteDC()
win32gui.ReleaseDC(hwin, hwindc)
win32gui.DeleteObject(bmp.GetHandle())

cv2.imshow('image', img)
0

1 Answer 1

0

The problem I was having wasn't that the bit of code below wasn't working:

signedIntsArray = bmp.GetBitmapBits(True)
img =  np.frombuffer(signedIntsArray, dtype='uint8')
img.shape = (h,w,4)

when I sent it to the cv2.imshow function as cv2.imshow('image', np.array(img), I realized I needed to set a waitKey:

cv2.imshow('image', np.array(screen_grab()))
cv2.waitKey(0)
cv2.destroyAllWindows()

This gave me what I was looking for. Hopefully this helps somebody in the future.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.