python screen-print does not capture drop-down menu on all windows applications

237 Views Asked by At

I have tested three different methods for capturing a windows screen containing a drop down menu. Neither method captures the drop-down menu. Could anybody explain to me how this could be achieved?

The image to be captured:

enter image description here

The resulting image after capture for all three methods

enter image description here

However, on for example Outlook the drop-down is captured correctly:

enter image description here

The capture script:

import numpy as np
from PIL import ImageGrab
import cv2
import os
import time
import datetime
from mss.windows import MSS as mss
import win32api
import win32gui
import ctypes

user32 = ctypes.windll.user32
dtwidth = user32.GetSystemMetrics(0)
dtheight = user32.GetSystemMetrics(1)

inputkey = {}
inpkeystat = False
mouse_state = 0

CLK_EMPTY = 0
CLK_OK = 1

env = os.environ
try:
    usrenv = env['TEMP']
except:
    usrenv = env['TMP']

BASEDIR = os.path.join(usrenv, './')

def get_click():
    global inputkey
    global mouse_state
    global inpkeystat

    (x, y) = (0, 0)
    wintext = ""
    retcode = CLK_EMPTY

    if inpkeystat == False:
        mouse_state = win32api.GetKeyState(0x01)
        inpkeystat = True

    mouseleft = win32api.GetKeyState(0x01)
    if mouseleft != mouse_state:  # Button state changed
        mouse_state = mouseleft
        if mouseleft < 0:
            # Left Button Pressed
            x, y = win32api.GetCursorPos()
            hwnd = win32gui.WindowFromPoint((x, y))
            wintext = win32gui.GetWindowText(hwnd)
            inpkeystat = False
            retcode = CLK_OK

    return retcode, wintext, (x, y)


logfile = os.path.join(BASEDIR, "scrnprintlog.txt")
date = datetime.datetime.now().strftime("%d-%m-%Y %I:%M%p")
printseq = 1

with open(logfile, "a") as myfile:
    myfile.write("-------------------------------------------\n")
    myfile.write(" Log screenprint test\n")
    myfile.write(date)
    myfile.write("\n-------------------------------------------\n")

print "-------------------------------------------"
print " Click mouse on screen to start capture"
print "-------------------------------------------"

while (True):
    clkevent, clkwin, (clkx, clky) = get_click()
    if clkevent == CLK_OK: break

while(True):
    (ax1, ay1, ax2, ay2) = (0, 0, dtwidth, dtheight)

    time.sleep(2)
    #method 1
    try:
        winImage = ImageGrab.grab((ax1, ay1, ax2, ay2))
        imgFile = 'scr-' + str(printseq) + '-pre-imggrab.png'
        imgSave = os.path.join(BASEDIR, imgFile)
        winImage.save(imgSave)

        date = datetime.datetime.now().strftime("%d-%m-%Y %I:%M%p")
        logstring = date + ': ' + imgFile + "\n"
        with open(logfile, "a") as myfile:
            myfile.write(logstring)
    except:
        pass

    #method 2
    try:
        sct = mss()
        imgFile = 'scr-' + str(printseq) + '-pre-shot.png'
        imgSave = os.path.join(BASEDIR, imgFile)
        sct.shot(mon=-1, output=imgSave)
        date = datetime.datetime.now().strftime("%d-%m-%Y %I:%M%p")
        logstring = date + ': ' + imgFile + "\n"
        with open(logfile, "a") as myfile:
            myfile.write(logstring)
    except:
        pass

    #method 3
    try:
        printscreen_pil =  ImageGrab.grab()
        printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype='uint8')\
                        .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))
        imgFile = 'scr-' + str(printseq) + '-pre-pil.png'
        imgSave = os.path.join(BASEDIR, imgFile)
        cv2.imwrite(imgSave, printscreen_numpy)
        date = datetime.datetime.now().strftime("%d-%m-%Y %I:%M%p")
        logstring = date + ': ' + imgFile + "\n"
        with open(logfile, "a") as myfile:
            myfile.write(logstring)
    except:
        pass

    print "-------------------------------------------\n"
    print "Click mouse for screen capture\n"

    while (True):
        clkevent, clkwin, (clkx, clky) = get_click()
        if clkevent == CLK_OK: break
    print "-------------------------------------------\n"

    printseq += 1
1

There are 1 best solutions below

1
On

As of MSS 3.1.2, this should be fixed. This issue was how we copy the screen content, see the full commit beb43a. The update is already available on PyPi.