# 📸 **BetterCam** 🚀
![World's Best AI Aimbot Banner](images/banner.png)
[![Pull Requests Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com)
> ***🌟 World's Fastest Python Screenshot Library for Windows 🐍***
```python
import bettercam
camera = bettercam.create()
camera.grab()
```
## 🌈 Introduction
BetterCam is the World's 🌏 Fastest Publicly available Python screenshot library for Windows, boasting 240Hz+ capturing using the Desktop Duplication API 🖥️💨. Born from [DXCam](https://github.com/ra1nty/DXcam), it shines in deep learning pipelines for FPS games, outpacing other Python solutions like [python-mss](https://github.com/BoboTiG/python-mss) and [D3DShot](https://github.com/SerpentAI/D3DShot/).
BetterCam's superpowers include:
- 🚅 Insanely fast screen capturing (> 240Hz)
- 🎮 Capture from Direct3D exclusive full-screen apps without interruption, even during alt+tab.
- 🔧 Auto-adjusts to scaled / stretched resolutions.
- 🎯 Precise FPS targeting for Video output.
- 👌 Smooth NumPy, OpenCV, PyTorch integration, etc.
> ***💞 Community contributions warmly invited!***
## 🛠️ Installation
### From PyPI:
```bash
pip install git+https://github.com/RootKit-Org/BetterCam
```
**Note:** 🧩 OpenCV is needed by BetterCam for color space conversion. Install it with `pip install opencv-python` if not yet available.
## 📚 Usage
Each monitor is paired with a `BetterCam` instance.
To get started:
```python
import bettercam
camera = bettercam.create() # Primary monitor's BetterCam instance
```
### 📷 Screenshot
For a quick snap, call `.grab`:
```python
frame = camera.grab()
```
`frame` is a `numpy.ndarray` in the `(Height, Width, 3[RGB])` format by default. Note: `.grab` may return `None` if there's no update since the last `.grab`.
To display your screenshot:
```python
from PIL import Image
Image.fromarray(frame).show()
```
For a specific region, provide the `region` parameter with a tuple for the bounding box coordinates:
```python
left, top = (1920 - 640) // 2, (1080 - 640) // 2
right, bottom = left + 640, top + 640
region = (left, top, right, bottom)
frame = camera.grab(region=region) # A 640x640x3 numpy ndarray snapshot
```
### 📹 Screen Capture
Start and stop screen capture with `.start` and `.stop`:
```python
camera.start(region=(left, top, right, bottom)) # Capture a region (optional)
camera.is_capturing # True
# ... Your Code
camera.stop()
camera.is_capturing # False
```
### 🔄 Retrieving Captured Data
When capturing, grab the latest frame with `.get_latest_frame`:
```python
camera.start()
for i in range(1000):
image = camera.get_latest_frame() # Waits for a new frame
camera.stop()
```
## ⚙️ Advanced Usage & Notes
### 🖥️ Multiple Monitors / GPUs
```python
cam1, cam2, cam3 = [bettercam.create(device_idx=d, output_idx=o) for d, o in [(0, 0), (0, 1), (1, 1)]]
img1, img2, img3 = [cam.grab() for cam in (cam1, cam2, cam3)]
```
To list devices and outputs:
```pycon
>>> import bettercam
>>> bettercam.device_info()
>>> bettercam.output_info()
```
### 🎨 Output Format
Select your color mode when creating a BetterCam instance:
```python
bettercam.create(output_idx=0, output_color="BGRA")
```
We support "RGB", "RGBA", "BGR", "BGRA", "GRAY" (for grayscale). Right now only `numpy.ndarray` shapes are supported: `(Height, Width, Channels)`.
### 🔄 Video Buffer
Frames go into a fixed-size ring buffer. Customize its max length with `max_buffer_len` on creation:
```python
camera = bettercam.create(max_buffer_len=512)
```
### 🎥 Target FPS
For precise FPS targeting, we use the high-resolution `CREATE_WAITABLE_TIMER_HIGH_RESOLUTION`:
```python
camera.start(target_fps=120) # Ideally, not beyond 240Hz.
```
### 🔄 Video Mode
For constant framerate video recording, use `video_mode=True` during `.start`:
```python
# Example: Record a 5-second, 120Hz video
camera.start(target_fps=target_fps, video_mode=True)
# ... Video writing code goes here
```
### 🛠️ Resource Management
Call `.release` to stop captures and free resources. Manual deletion also possible:
```python
del camera
```
## 📊 Benchmarks
### Max FPS Achievement:
```python
cam = bettercam.create()
# ... Benchmarking code...
```
| | BetterCam Nvidia GPU :checkered_flag: | BetterCam :checkered_flag: | DXCam | python-mss | D3DShot |
|---------|---------------------------------------|--------------------------|--------|------------|---------|
| Avg FPS | 111.667 | 123.667 | 39 | 34.667 | N/A |
| Std Dev | 0.889 | 1.778 | 1.333 | 2.222 | N/A |
### FPS Targeting:
```python
# ... Sample code to test target FPS ...
```
| Target/Result | BetterCam Nvidia GPU :checkered_flag: | BetterCam :checkered_flag: | DXCam | python-mss | D3DShot |
|---------------|---------------------------------------|--------------------------|-------|------------|---------|
| 120fps | 111.667, 0.889 | 88.333, 2.444 | 36.667, 0.889 | N/A | N/A |
| 60fps | 60, 0 | 60, 0 | 35, 5.3 | N/A | N/A |
## 📝 Referenced Work
- [DXCam](https://github.com/ra1nty/DXcam): Our origin story.
- [D3DShot](https://github.com/SerpentAI/D3DShot/): Provided foundational ctypes.
- [OBS Studio](https://github.com/obsproject/obs-studio): A treasure trove of knowledge.
[^1]: [Preemption (computing)](https://en.wikipedia.org/wiki/Preemption_(computing))
[^2]: [Time.sleep precision improvement](https://github.com/python/cpython/issues/65501)
Raw data
{
"_id": null,
"home_page": "https://github.com/RootKit-Org/BetterCam",
"name": "bettercam",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "screen,screenshot,screencapture,screengrab,windows",
"author": "Qfc9",
"author_email": "eharmon@rootkit.org",
"download_url": "https://files.pythonhosted.org/packages/96/27/bf39ca1caaaac0aedfdc77929608b316cce2bab7fc6f5f2643e3c107793b/bettercam-1.0.0.tar.gz",
"platform": null,
"description": "# \ud83d\udcf8 **BetterCam** \ud83d\ude80\r\n![World's Best AI Aimbot Banner](images/banner.png)\r\n\r\n[![Pull Requests Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com)\r\n> ***\ud83c\udf1f World's Fastest Python Screenshot Library for Windows \ud83d\udc0d***\r\n\r\n```python\r\nimport bettercam\r\ncamera = bettercam.create()\r\ncamera.grab()\r\n```\r\n\r\n## \ud83c\udf08 Introduction\r\nBetterCam is the World's \ud83c\udf0f Fastest Publicly available Python screenshot library for Windows, boasting 240Hz+ capturing using the Desktop Duplication API \ud83d\udda5\ufe0f\ud83d\udca8. Born from [DXCam](https://github.com/ra1nty/DXcam), it shines in deep learning pipelines for FPS games, outpacing other Python solutions like [python-mss](https://github.com/BoboTiG/python-mss) and [D3DShot](https://github.com/SerpentAI/D3DShot/).\r\n\r\nBetterCam's superpowers include:\r\n- \ud83d\ude85 Insanely fast screen capturing (> 240Hz)\r\n- \ud83c\udfae Capture from Direct3D exclusive full-screen apps without interruption, even during alt+tab.\r\n- \ud83d\udd27 Auto-adjusts to scaled / stretched resolutions.\r\n- \ud83c\udfaf Precise FPS targeting for Video output.\r\n- \ud83d\udc4c Smooth NumPy, OpenCV, PyTorch integration, etc.\r\n\r\n> ***\ud83d\udc9e Community contributions warmly invited!***\r\n\r\n## \ud83d\udee0\ufe0f Installation\r\n### From PyPI:\r\n```bash\r\npip install git+https://github.com/RootKit-Org/BetterCam\r\n```\r\n\r\n**Note:** \ud83e\udde9 OpenCV is needed by BetterCam for color space conversion. Install it with `pip install opencv-python` if not yet available.\r\n\r\n\r\n## \ud83d\udcda Usage\r\nEach monitor is paired with a `BetterCam` instance.\r\nTo get started:\r\n```python\r\nimport bettercam\r\ncamera = bettercam.create() # Primary monitor's BetterCam instance\r\n```\r\n### \ud83d\udcf7 Screenshot\r\nFor a quick snap, call `.grab`:\r\n```python\r\nframe = camera.grab()\r\n```\r\n`frame` is a `numpy.ndarray` in the `(Height, Width, 3[RGB])` format by default. Note: `.grab` may return `None` if there's no update since the last `.grab`.\r\n\r\nTo display your screenshot:\r\n```python\r\nfrom PIL import Image\r\nImage.fromarray(frame).show()\r\n```\r\nFor a specific region, provide the `region` parameter with a tuple for the bounding box coordinates:\r\n```python\r\nleft, top = (1920 - 640) // 2, (1080 - 640) // 2\r\nright, bottom = left + 640, top + 640\r\nregion = (left, top, right, bottom)\r\nframe = camera.grab(region=region) # A 640x640x3 numpy ndarray snapshot\r\n```\r\n\r\n### \ud83d\udcf9 Screen Capture\r\nStart and stop screen capture with `.start` and `.stop`:\r\n```python\r\ncamera.start(region=(left, top, right, bottom)) # Capture a region (optional)\r\ncamera.is_capturing # True\r\n# ... Your Code\r\ncamera.stop()\r\ncamera.is_capturing # False\r\n```\r\n\r\n### \ud83d\udd04 Retrieving Captured Data\r\nWhen capturing, grab the latest frame with `.get_latest_frame`:\r\n```python\r\ncamera.start()\r\nfor i in range(1000):\r\n image = camera.get_latest_frame() # Waits for a new frame\r\ncamera.stop()\r\n```\r\n\r\n## \u2699\ufe0f Advanced Usage & Notes\r\n### \ud83d\udda5\ufe0f Multiple Monitors / GPUs\r\n```python\r\ncam1, cam2, cam3 = [bettercam.create(device_idx=d, output_idx=o) for d, o in [(0, 0), (0, 1), (1, 1)]]\r\nimg1, img2, img3 = [cam.grab() for cam in (cam1, cam2, cam3)]\r\n```\r\nTo list devices and outputs:\r\n```pycon\r\n>>> import bettercam\r\n>>> bettercam.device_info()\r\n>>> bettercam.output_info()\r\n```\r\n\r\n### \ud83c\udfa8 Output Format\r\nSelect your color mode when creating a BetterCam instance:\r\n```python\r\nbettercam.create(output_idx=0, output_color=\"BGRA\")\r\n```\r\nWe support \"RGB\", \"RGBA\", \"BGR\", \"BGRA\", \"GRAY\" (for grayscale). Right now only `numpy.ndarray` shapes are supported: `(Height, Width, Channels)`.\r\n\r\n### \ud83d\udd04 Video Buffer\r\nFrames go into a fixed-size ring buffer. Customize its max length with `max_buffer_len` on creation:\r\n```python\r\ncamera = bettercam.create(max_buffer_len=512)\r\n```\r\n\r\n### \ud83c\udfa5 Target FPS\r\nFor precise FPS targeting, we use the high-resolution `CREATE_WAITABLE_TIMER_HIGH_RESOLUTION`:\r\n```python\r\ncamera.start(target_fps=120) # Ideally, not beyond 240Hz.\r\n```\r\n\r\n### \ud83d\udd04 Video Mode\r\nFor constant framerate video recording, use `video_mode=True` during `.start`:\r\n```python\r\n# Example: Record a 5-second, 120Hz video\r\ncamera.start(target_fps=target_fps, video_mode=True)\r\n# ... Video writing code goes here\r\n```\r\n\r\n### \ud83d\udee0\ufe0f Resource Management\r\nCall `.release` to stop captures and free resources. Manual deletion also possible:\r\n```python\r\ndel camera\r\n```\r\n\r\n## \ud83d\udcca Benchmarks\r\n### Max FPS Achievement:\r\n```python\r\ncam = bettercam.create()\r\n# ... Benchmarking code...\r\n```\r\n| | BetterCam Nvidia GPU :checkered_flag: | BetterCam :checkered_flag: | DXCam | python-mss | D3DShot |\r\n|---------|---------------------------------------|--------------------------|--------|------------|---------|\r\n| Avg FPS | 111.667 | 123.667 | 39 | 34.667 | N/A |\r\n| Std Dev | 0.889 | 1.778 | 1.333 | 2.222 | N/A |\r\n\r\n### FPS Targeting:\r\n```python\r\n# ... Sample code to test target FPS ...\r\n```\r\n| Target/Result | BetterCam Nvidia GPU :checkered_flag: | BetterCam :checkered_flag: | DXCam | python-mss | D3DShot |\r\n|---------------|---------------------------------------|--------------------------|-------|------------|---------|\r\n| 120fps | 111.667, 0.889 | 88.333, 2.444 | 36.667, 0.889 | N/A | N/A |\r\n| 60fps | 60, 0 | 60, 0 | 35, 5.3 | N/A | N/A |\r\n\r\n## \ud83d\udcdd Referenced Work\r\n- [DXCam](https://github.com/ra1nty/DXcam): Our origin story.\r\n- [D3DShot](https://github.com/SerpentAI/D3DShot/): Provided foundational ctypes.\r\n- [OBS Studio](https://github.com/obsproject/obs-studio): A treasure trove of knowledge.\r\n\r\n[^1]: [Preemption (computing)](https://en.wikipedia.org/wiki/Preemption_(computing))\r\n[^2]: [Time.sleep precision improvement](https://github.com/python/cpython/issues/65501)\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Python high-performance screenshot library for Windows use Desktop Duplication API",
"version": "1.0.0",
"project_urls": {
"Homepage": "https://github.com/RootKit-Org/BetterCam",
"Source": "https://github.com/RootKit-Org/BetterCam",
"Tracker": "https://github.com/RootKit-Org/BetterCam/issues"
},
"split_keywords": [
"screen",
"screenshot",
"screencapture",
"screengrab",
"windows"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "3c66c16181c6e036e60f41161ea31f78d4ffe76babbdad1e82499226e55bfecf",
"md5": "5d005dc3f8bfcd29627f17d7a06964d1",
"sha256": "0690b2289683725d875eb877db13a8c628935816866ef8ec0751945e988f32ac"
},
"downloads": -1,
"filename": "bettercam-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5d005dc3f8bfcd29627f17d7a06964d1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 21029,
"upload_time": "2023-11-22T08:25:13",
"upload_time_iso_8601": "2023-11-22T08:25:13.676300Z",
"url": "https://files.pythonhosted.org/packages/3c/66/c16181c6e036e60f41161ea31f78d4ffe76babbdad1e82499226e55bfecf/bettercam-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "9627bf39ca1caaaac0aedfdc77929608b316cce2bab7fc6f5f2643e3c107793b",
"md5": "90701fddf7aed89b7824c8f933f7a11f",
"sha256": "122cc0e905cb40be8f2a26e46ee587bae40c10eb9c23201370a54e68b84a0940"
},
"downloads": -1,
"filename": "bettercam-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "90701fddf7aed89b7824c8f933f7a11f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 19269,
"upload_time": "2023-11-22T08:25:15",
"upload_time_iso_8601": "2023-11-22T08:25:15.705692Z",
"url": "https://files.pythonhosted.org/packages/96/27/bf39ca1caaaac0aedfdc77929608b316cce2bab7fc6f5f2643e3c107793b/bettercam-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-22 08:25:15",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "RootKit-Org",
"github_project": "BetterCam",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "bettercam"
}