Skip to content

A fast Python API for retrieving RGB values of a pixel on Windows using C extensions and ctypes.

Notifications You must be signed in to change notification settings

winstxnhdw/PixWin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

84 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PixWin

python linting: pylint main.yml formatter.yml dependabot.yml

PixWin is a fast Python API for retrieving RGB values of a pixel on Windows. It uses Python C extensions and ctypes to access GetPixel() within the Win32 API.

Installation

pip install git+https://github.com/winstxnhdw/PixWin

Usage

from pixwin import PixWin


def loop(pixwin: PixWin):

    while True:
        print(pixwin.get_pixel(420, 69))        # e.g. (42, 21, 13)
        print(pixwin.get_red_value(420, 69))    # e.g. 42
        print(pixwin.get_blue_value(420, 69))   # e.g. 21
        print(pixwin.get_green_value(420, 69))  # e.g. 13


def main():

    with PixWin() as pixwin:
        try:
            loop(pixwin)

        except KeyboardInterrupt:
            print('Manual exit detected.')


if __name__ == '__main__':
    main()

Benchmarks

Similar to PixWin, PyScreeze retrieves pixel values via the Win32 API. PixWin is ~15000x faster than PyScreeze.

Single-pixel retrieval

PixWin
from cProfile import run
from pixwin import PixWin


with PixWin() as pixwin:
    def get_pixel():
        """
        Summary
        -------
        retrieve a single pixel value
        """
        pixwin.get_pixel(0, 0)


if __name__ == '__main__':
    run('get_pixel()')
6 function calls in 0.000 seconds

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.000    0.000 <string>:1(<module>)
    1    0.000    0.000    0.000    0.000 __init__.py:33(get_pixel)
    1    0.000    0.000    0.000    0.000 test.py:5(pixwin)
    1    0.000    0.000    0.000    0.000 {built-in method builtins.exec}
    1    0.000    0.000    0.000    0.000 {built-in method pixwin.get_pixel.get_rgb}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
asweigart/pyscreeze
from cProfile import run
from pyscreeze import pixel


def pyscreeze():
    """
    Summary
    -------
    retrieve a single pixel value
    """
    pixel(0, 0)


if __name__ == '__main__':
    run('pyscreeze()')
41 function calls in 0.007 seconds

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.007    0.007 <string>:1(<module>)
    2    0.000    0.000    0.000    0.000 __init__.py:110(__win32_openDC)
    1    0.000    0.000    0.000    0.000 __init__.py:340(__init__)
    1    0.000    0.000    0.000    0.000 __init__.py:368(_FuncPtr)
    3    0.000    0.000    0.000    0.000 __init__.py:391(__getitem__)
    1    0.000    0.000    0.000    0.000 __init__.py:441(__getattr__)
    1    0.007    0.007    0.007    0.007 __init__.py:601(pixel)
    4    0.000    0.000    0.000    0.000 __init__.py:613(<genexpr>)
    1    0.000    0.000    0.000    0.000 contextlib.py:102(__init__)
    1    0.000    0.000    0.000    0.000 contextlib.py:130(__enter__)
    1    0.000    0.000    0.000    0.000 contextlib.py:139(__exit__)
    1    0.000    0.000    0.000    0.000 contextlib.py:279(helper)
    1    0.000    0.000    0.007    0.007 test.py:12(pyscreeze)
    1    0.000    0.000    0.000    0.000 {built-in method _ctypes.LoadLibrary}
    1    0.000    0.000    0.000    0.000 {built-in method builtins.__build_class__}
    1    0.000    0.000    0.007    0.007 {built-in method builtins.exec}
    1    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}
    3    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}
    2    0.000    0.000    0.000    0.000 {built-in method builtins.next}
    4    0.000    0.000    0.000    0.000 {built-in method builtins.setattr}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    1    0.000    0.000    0.000    0.000 {method 'format' of 'str' objects}
    4    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

Multi-pixel retrieval

PixWin
import cProfile as profile
from pixwin import PixWin


with PixWin() as pixwin:
    def get_pixel():
        """
        Summary
        -------
        retrieve multiple pixel values
        """
        [pixwin.get_pixel(0, 0) for _ in range(10000)]


if __name__ == '__main__':
    profile.run('get_pixel()')
20004 function calls in 0.006 seconds

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.006    0.006 <string>:1(<module>)
10000    0.002    0.000    0.004    0.000 __init__.py:33(get_pixel)
    1    0.000    0.000    0.006    0.006 test.py:5(pixwin)
    1    0.002    0.002    0.006    0.006 test.py:6(<listcomp>)
    1    0.000    0.000    0.006    0.006 {built-in method builtins.exec}
10000    0.003    0.000    0.003    0.000 {built-in method pixwin.get_pixel.get_rgb}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
asweigart/pyscreeze
from cProfile import run
from pyscreeze import pixel


def pyscreeze():
    """
    Summary
    -------
    retrieve multiple pixel values
    """
    [pixel(0, 0) for _ in range(10000)]


if __name__ == '__main__':
    run('pyscreeze()')
150027 function calls in 89.460 seconds

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000   89.460   89.460 <string>:1(<module>)
20000    0.310    0.000    0.310    0.000 __init__.py:110(__win32_openDC)
    1    0.000    0.000    0.000    0.000 __init__.py:340(__init__)
    1    0.000    0.000    0.000    0.000 __init__.py:368(_FuncPtr)
    3    0.000    0.000    0.000    0.000 __init__.py:384(__getattr__)
    3    0.000    0.000    0.000    0.000 __init__.py:391(__getitem__)
    1    0.000    0.000    0.000    0.000 __init__.py:441(__getattr__)
10000   88.936    0.009   89.440    0.009 __init__.py:601(pixel)
40000    0.044    0.000    0.044    0.000 __init__.py:613(<genexpr>)
10000    0.029    0.000    0.035    0.000 contextlib.py:102(__init__)
10000    0.010    0.000    0.123    0.000 contextlib.py:130(__enter__)
10000    0.029    0.000    0.241    0.000 contextlib.py:139(__exit__)
10000    0.014    0.000    0.049    0.000 contextlib.py:279(helper)
    1    0.000    0.000   89.460   89.460 test.py:5(pyscreeze)
    1    0.019    0.019   89.460   89.460 test.py:7(<listcomp>)
    1    0.000    0.000    0.000    0.000 {built-in method _ctypes.LoadLibrary}
    1    0.000    0.000    0.000    0.000 {built-in method builtins.__build_class__}
    1    0.000    0.000   89.460   89.460 {built-in method builtins.exec}
10000    0.006    0.000    0.006    0.000 {built-in method builtins.getattr}
    3    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}
20000    0.015    0.000    0.325    0.000 {built-in method builtins.next}
    4    0.000    0.000    0.000    0.000 {built-in method builtins.setattr}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
10000    0.048    0.000    0.048    0.000 {method 'format' of 'str' objects}
    4    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}

Development

You can build locally by running the following.

poetry build

About

A fast Python API for retrieving RGB values of a pixel on Windows using C extensions and ctypes.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published