Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
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: 13 days 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 (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-10-16T10:43:03.000Z (20 days ago)
- Last Synced: 2024-10-18T05:44:00.219Z (18 days ago)
- Topics: ctypes, getpixel, pyscreeze, python-c-extension, win32-api
- Language: Python
- Homepage:
- Size: 146 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# PixWin
[![python](https://img.shields.io/badge/python-3.8%20|%203.9%20|%203.10%20|%203.11%20|%203.12-blue)](https://www.python.org/)
[![linting: pylint](https://img.shields.io/badge/linting-pylint-yellowgreen)](https://github.com/PyCQA/pylint)
[![main.yml](https://github.com/winstxnhdw/PixWin/actions/workflows/main.yml/badge.svg)](https://github.com/winstxnhdw/PixWin/actions/workflows/main.yml)
[![formatter.yml](https://github.com/winstxnhdw/PixWin/actions/workflows/formatter.yml/badge.svg)](https://github.com/winstxnhdw/PixWin/actions/workflows/formatter.yml)
[![dependabot.yml](https://github.com/winstxnhdw/PixWin/actions/workflows/dependabot.yml/badge.svg)](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 PixWindef 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. 13def 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 PixWinwith 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 secondsncalls 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 pixeldef pyscreeze():
"""
Summary
-------
retrieve a single pixel value
"""
pixel(0, 0)if __name__ == '__main__':
run('pyscreeze()')
``````txt
41 function calls in 0.007 secondsncalls 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 PixWinwith 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 secondsncalls 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 pixeldef 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 secondsncalls 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
```