0

I want to display some information on screen, based on the position of some pdf page being shown. For that, I need to get the position of the page's border, but right now, I only have a very naive and inefficient solution, which consists in taking vertical slices of the window until I detect a 'mostly white' slice, which I take as the searched border:

import win32gui
from win32api import GetSystemMetrics

dc = win32gui.GetDC(0)
width,height=GetSystemMetrics(0),GetSystemMetrics(1)

fraction=200 # This is to reduce the amount of info to be processed
p_height=height/fraction    
suma=0 # This variable holds the number of withe pixels of each slice

for i in range(width): # while in screen w
    for j in range(int(p_height)): # hile in screen h
        if win32gui.GetPixel(dc, i, j*fraction)!=16777215: 
            pass # pass if pixel is not withe
        else:
            suma+=1
    if suma/p_height>0.4: # if more than 40% of the pixels are white,
        print(i)
        break
    else:
        suma=0

This is both slow and not smart. I guess there's a way to get the information I'm looking for without having to literally 'look' at the screen. Any suggestions?

(I use google chrome to open the pdf.)

martineau
  • 119,623
  • 25
  • 170
  • 301
José Chamorro
  • 497
  • 1
  • 6
  • 21
  • 1
    Unless you can interact directly with the application displaying the PDF directly through some API to get the information, my gess is there probably isn't any better way. – martineau Aug 19 '20 at 01:55
  • You may need to think more. If the chrome is not full screen, perhaps it only occupies a quarter of the screen, then you must detect less than 40% of the white area (PDF file) of the screen. – Strive Sun Aug 20 '20 at 09:16
  • 1
    If you are sure that chrome is full screen, then I can suggest you to use `CreateDIBSection` to get the pixel value, which is faster than `GetPixel`. Refer: [Get Pixel color fastest way?](https://stackoverflow.com/a/10516660/11128312) – Strive Sun Aug 20 '20 at 09:18
  • Thanks for that, I'll take a look on CreateDIBSection, sorry I didn't get the notification of your comment before. About the full screen thing, I guess it won't be difficult to detect the size and position of the chrome screen to adapt my code, but I have to assume the possibility of the user reading on full screen, so that's why I started there. I did improve my code a little, I would appreciate any comments on that improvement. I'll upload it later today – José Chamorro Aug 25 '20 at 21:24
  • 1
    Hi, have your question been solved? – Strive Sun Sep 02 '20 at 06:34
  • @StriveSun-MSFT Not yet u.u – José Chamorro Sep 06 '20 at 18:00
  • 1
    Please update in the question. – Strive Sun Sep 08 '20 at 07:16
  • @StriveSun-MSFT I just did (y) – José Chamorro Sep 24 '20 at 02:55

1 Answers1

0

Just for the sake of keeping this question alive, here's a little improvement to my original code meant to save some time. In practice, it takes the code more than a second to find the page, which is not acceptable.

I just introduced a 'step' to ignore some screen slices in order to find the mostly-white section of the screen faster, and then go back slowly to find the exact starting point of that section.

import win32gui
from win32api import GetSystemMetrics

dc = win32gui.GetDC(0)
width,height=GetSystemMetrics(0),GetSystemMetrics(1)

fraction=200 # This is to reduce the amount of info to be processed
step=10 # Here, the code will look at one of every ten vertical slices

p_height=height/fraction    
suma=0 # This variable holds the number of withe pixels of each slice
for i in range(0,width,step): # while in screen w
    for j in range(int(p_height)): # while in screen h
        if win32gui.GetPixel(dc, i, j*fraction)!=16777215: 
            pass # pass if pixel is not withe
        else:
            suma+=1
    if suma/p_height>0.4: # if more than 40% of the pixels are white
        suma=0
        for k in range(step): # to cover the ignored slices
            for j in range(int(p_height)): # while in screen h
                if win32gui.GetPixel(dc, (i-k), j*fraction)!=16777215: 
                    pass # pass if pixel is not withe
                else:
                    suma+=1
            if suma/p_height<0.4: # If less than 40% of pixels are white, we found the edge
                print(i-k)
                break
            else:
                suma=0
         break
    else:
        suma=0
José Chamorro
  • 497
  • 1
  • 6
  • 21