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

248 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
Tiger-222 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.