coreimr 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- coreimr-1.0.0/PKG-INFO +6 -0
- coreimr-1.0.0/README.md +45 -0
- coreimr-1.0.0/coreimr/__init__.py +83 -0
- coreimr-1.0.0/coreimr.egg-info/PKG-INFO +6 -0
- coreimr-1.0.0/coreimr.egg-info/SOURCES.txt +7 -0
- coreimr-1.0.0/coreimr.egg-info/dependency_links.txt +1 -0
- coreimr-1.0.0/coreimr.egg-info/top_level.txt +1 -0
- coreimr-1.0.0/setup.cfg +4 -0
- coreimr-1.0.0/setup.py +10 -0
coreimr-1.0.0/PKG-INFO
ADDED
coreimr-1.0.0/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# CoreImR
|
|
2
|
+
|
|
3
|
+
Advanced, Zero-dependency HTML, CSS, and JS to Image converter for Python.
|
|
4
|
+
|
|
5
|
+
It simply opens a temporary HTML file in a headless browser (Chrome or Edge) that is already installed on the system and takes a screenshot. 100% zero-dependency, lightweight, fast, and feature-rich!
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
- **Zero Dependencies**
|
|
9
|
+
- Configurable **Dimensions** (Width/Height)
|
|
10
|
+
- Support for **Transparent Backgrounds**
|
|
11
|
+
- **Delay / Virtual Time Budget** (wait for animations/JS to load before capture)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install coreimr
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Simple Example
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from coreimr import render
|
|
25
|
+
|
|
26
|
+
render('<h1>Hello!</h1>', 'output.png')
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Advanced Example
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from coreimr import CoreImR
|
|
33
|
+
|
|
34
|
+
html = """
|
|
35
|
+
<!DOCTYPE html>
|
|
36
|
+
<html>
|
|
37
|
+
<body style="background: rgba(0, 0, 255, 0.5); width: 100vw; height: 100vh; display: flex; align-items: center; justify-content: center;">
|
|
38
|
+
<h1 style="color: white; font-family: sans-serif;">Advanced CoreImR!</h1>
|
|
39
|
+
</body>
|
|
40
|
+
</html>
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
imr = CoreImR(width=1920, height=1080, transparent=True, delay=500)
|
|
44
|
+
imr.render(html, 'output_advanced.png')
|
|
45
|
+
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import tempfile
|
|
4
|
+
import subprocess
|
|
5
|
+
import time
|
|
6
|
+
import random
|
|
7
|
+
|
|
8
|
+
class BrowserNotFoundError(Exception):
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
class RenderError(Exception):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
def _find_browser() -> str:
|
|
15
|
+
if sys.platform == 'win32':
|
|
16
|
+
paths = [
|
|
17
|
+
r'C:\Program Files\Google\Chrome\Application\chrome.exe',
|
|
18
|
+
r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe',
|
|
19
|
+
r'C:\Program Files\Microsoft\Edge\Application\msedge.exe',
|
|
20
|
+
r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
|
|
21
|
+
]
|
|
22
|
+
elif sys.platform == 'darwin':
|
|
23
|
+
paths = ['/Applications/Google Chrome.app/Contents/MacOS/Google Chrome']
|
|
24
|
+
else:
|
|
25
|
+
paths = ['/usr/bin/google-chrome', '/usr/bin/chromium-browser', '/usr/bin/chromium']
|
|
26
|
+
|
|
27
|
+
for p in paths:
|
|
28
|
+
if os.path.exists(p):
|
|
29
|
+
return p
|
|
30
|
+
raise BrowserNotFoundError("No compatible browser (Chrome/Edge) found on system.")
|
|
31
|
+
|
|
32
|
+
class CoreImR:
|
|
33
|
+
"""
|
|
34
|
+
Advanced configuration class for rendering HTML to images.
|
|
35
|
+
"""
|
|
36
|
+
def __init__(self, width: int = 1280, height: int = 720, transparent: bool = False, delay: int = 0, browser_path: str = None):
|
|
37
|
+
self.width = width
|
|
38
|
+
self.height = height
|
|
39
|
+
self.transparent = transparent
|
|
40
|
+
self.delay = delay
|
|
41
|
+
self.browser_path = browser_path or _find_browser()
|
|
42
|
+
|
|
43
|
+
def render(self, html: str, output_path: str) -> bool:
|
|
44
|
+
fd, tmp_html = tempfile.mkstemp(suffix=f'_coreimr_{random.randint(1000, 9999)}.html')
|
|
45
|
+
with os.fdopen(fd, 'w', encoding='utf-8') as f:
|
|
46
|
+
f.write(html)
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
abs_output = os.path.abspath(output_path)
|
|
50
|
+
cmd = [
|
|
51
|
+
self.browser_path,
|
|
52
|
+
'--headless',
|
|
53
|
+
'--disable-gpu',
|
|
54
|
+
'--hide-scrollbars',
|
|
55
|
+
f'--window-size={self.width},{self.height}',
|
|
56
|
+
f'--screenshot={abs_output}'
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
if self.transparent:
|
|
60
|
+
cmd.append('--default-background-color=00000000')
|
|
61
|
+
if self.delay > 0:
|
|
62
|
+
cmd.append(f'--virtual-time-budget={self.delay}')
|
|
63
|
+
|
|
64
|
+
cmd.append(f'file://{tmp_html}')
|
|
65
|
+
|
|
66
|
+
result = subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
67
|
+
if result.returncode != 0:
|
|
68
|
+
raise RenderError(f"Browser command failed with exit code {result.returncode}")
|
|
69
|
+
|
|
70
|
+
return True
|
|
71
|
+
finally:
|
|
72
|
+
try:
|
|
73
|
+
os.remove(tmp_html)
|
|
74
|
+
except Exception:
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
def render(html: str, output_path: str, **kwargs) -> bool:
|
|
78
|
+
"""
|
|
79
|
+
Convenience function to render HTML string to an image file.
|
|
80
|
+
Accepts kwargs: width, height, transparent, delay, browser_path
|
|
81
|
+
"""
|
|
82
|
+
instance = CoreImR(**kwargs)
|
|
83
|
+
return instance.render(html, output_path)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
coreimr
|
coreimr-1.0.0/setup.cfg
ADDED