https://github.com/winstxnhdw/pixwin
A fast Python API for retrieving RGB values of a pixel on Windows using C extensions and ctypes.
https://github.com/winstxnhdw/pixwin
ctypes getpixel pyscreeze python-c-extension win32-api
Last synced: about 1 year ago
JSON representation
A fast Python API for retrieving RGB values of a pixel on Windows using C extensions and ctypes.
- Host: GitHub
- URL: https://github.com/winstxnhdw/pixwin
- Owner: winstxnhdw
- Created: 2022-11-09T00:52:08.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-05-02T10:56:28.000Z (about 1 year ago)
- Last Synced: 2025-05-02T11:47:51.817Z (about 1 year ago)
- Topics: ctypes, getpixel, pyscreeze, python-c-extension, win32-api
- Language: Python
- Homepage:
- Size: 234 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# PixWin
[](https://www.python.org/)
[](https://github.com/PyCQA/pylint)
[](https://github.com/winstxnhdw/PixWin/actions/workflows/main.yml)
[](https://github.com/winstxnhdw/PixWin/actions/workflows/formatter.yml)
[](https://github.com/winstxnhdw/PixWin/actions/workflows/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()](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getpixel) within the Win32 API.
## Installation
```bash
pip install git+https://github.com/winstxnhdw/PixWin
```
## Usage
```python
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](https://github.com/asweigart/pyscreeze) retrieves pixel values via the Win32 API. PixWin is ~15000x faster than [PyScreeze](https://github.com/asweigart/pyscreeze).
### Single-pixel retrieval
PixWin
```python
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()')
```
```txt
6 function calls in 0.000 seconds
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 :1()
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}
```
```python
from cProfile import run
from pyscreeze import pixel
def pyscreeze():
"""
Summary
-------
retrieve a single pixel value
"""
pixel(0, 0)
if __name__ == '__main__':
run('pyscreeze()')
```
```txt
41 function calls in 0.007 seconds
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.007 0.007 :1()
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()
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
```python
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()')
```
```txt
20004 function calls in 0.006 seconds
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.006 0.006 :1()
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()
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}
```
```python
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()')
```
```txt
150027 function calls in 89.460 seconds
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 89.460 89.460 :1()
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()
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()
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.
```bash
poetry build
```