|
| 1 | +from base64 import b64decode |
1 | 2 | from typing import Callable |
2 | 3 | import threading |
3 | 4 | import time |
4 | 5 | import functools |
| 6 | +import pathlib |
5 | 7 |
|
6 | 8 | from . import platform |
7 | | -from .utils import get_device |
| 9 | +from .utils import get_device, read_texture |
8 | 10 | from .webgpu_api import * |
9 | 11 |
|
10 | 12 | _TARGET_FPS = 60 |
@@ -169,6 +171,23 @@ def on_resize(self, func: Callable): |
169 | 171 | def on_update_html_canvas(self, func: Callable): |
170 | 172 | self._on_update_html_canvas.append(func) |
171 | 173 |
|
| 174 | + def save_screenshot(self, filename: str): |
| 175 | + with self._update_mutex: |
| 176 | + path = pathlib.Path(filename) |
| 177 | + format = path.suffix[1:] |
| 178 | + data = read_texture(self.target_texture) |
| 179 | + canvas = platform.js.document.createElement("canvas") |
| 180 | + canvas.width = self.width |
| 181 | + canvas.height = self.height |
| 182 | + ctx = canvas.getContext("2d") |
| 183 | + u8 = platform.js.Uint8ClampedArray._new(data.tobytes()) |
| 184 | + image_data = platform.js.ImageData._new( |
| 185 | + u8, self.width, self.height |
| 186 | + ) |
| 187 | + ctx.putImageData(image_data, 0, 0) |
| 188 | + canvas.remove() |
| 189 | + path.write_bytes(b64decode(canvas.toDataURL(format).split(",")[1])) |
| 190 | + |
172 | 191 | @debounce(5) |
173 | 192 | def resize(self): |
174 | 193 | with self._update_mutex: |
|
0 commit comments