Convert HTML + CSS to images without a browser
Project description
html2pic
Convert HTML + CSS to beautiful images using PicTex
html2pic is a Python library that translates a subset of HTML and CSS to high-quality images without requiring a browser engine. Built on top of PicTex, it provides a powerful and intuitive way to generate images from web markup.
⚠️ Experimental Software Notice
This is experimental software developed primarily using AI assistance (Claude Code). While functional, it should be used with caution in production environments. Key considerations:
- Rapid Development: Most of the codebase was generated and refined through AI-assisted programming
- Limited Testing: Extensive testing in diverse environments is still ongoing
- Active Development: APIs and behavior may change significantly in future versions
- Community Feedback Welcome: Please report issues and suggest improvements via GitHub
Use this library for prototyping, experimentation, and non-critical applications. For production use, thorough testing is recommended.
🚀 Key Features
- No Browser Required: Pure Python implementation using PicTex as the rendering engine
- Flexbox Support: Modern CSS layout with
display: flex,justify-content,align-items, etc. - Rich Typography: Font families, sizes, weights, colors, text decorations, and @font-face support
- Box Model: Complete support for padding, margins, borders, and border-radius
- Responsive Sizing: Supports px, em, rem, % units and flexible sizing modes
- High Quality Output: Vector (SVG) and raster (PNG, JPG) output formats
- Simple API: Clean, intuitive interface inspired by modern web development
📦 Installation
pip install html2pic
🎯 Quick Start
from html2pic import Html2Pic
# Your HTML content
html = '''
<div class="card">
<h1>Hello, World!</h1>
<p class="subtitle">Generated with html2pic</p>
</div>
'''
# Your CSS styles
css = '''
.card {
display: flex;
flex-direction: column;
align-items: center;
padding: 30px;
background-color: #f0f8ff;
border-radius: 15px;
width: 300px;
}
h1 {
color: #2c3e50;
font-size: 28px;
margin: 0 0 10px 0;
}
.subtitle {
color: #7f8c8d;
font-size: 16px;
margin: 0;
}
'''
# Create and render
renderer = Html2Pic(html, css)
image = renderer.render()
image.save("output.png")
🏗️ Architecture
html2pic works by translating HTML + CSS concepts to PicTex builders:
- HTML Parser: Uses BeautifulSoup to create a DOM tree
- CSS Parser: Uses tinycss2 to extract style rules
- Style Engine: Applies CSS cascade, specificity, and inheritance
- Translator: Maps styled DOM nodes to PicTex builders (Canvas, Row, Column, Text, Image)
- Renderer: Uses PicTex to generate the final image
📋 Supported HTML/CSS Features
HTML Elements
<div>,<section>,<article>→ Layout containers<h1>-<h6>,<p>,<span>→ Text elements<img>→ Image elements
CSS Layout
display: flexwithflex-direction: row|columndisplay: nonefor hiding elements completelyjustify-content:flex-start,center,flex-end,space-between,space-around,space-evenlyalign-items:flex-start,center,flex-end,stretchgapfor spacing between flex items
CSS Box Model
width,height(px, %, auto, fit-content, fill-available)padding,margin(shorthand and individual sides)borderwith width, style (solid, dashed, dotted), and colorborder-radius(px and %) with full individual corner support- Individual properties:
border-top-left-radius,border-top-right-radius,border-bottom-left-radius,border-bottom-right-radius
- Individual properties:
background-color(solid colors, linear gradients, and RGBA with alpha channel)background-image(url() and linear-gradient())background-size(cover, contain, tile for images)box-shadow(offset-x, offset-y, blur-radius, color with RGBA support)
CSS Typography
font-family,font-size,font-weight,font-stylecolor,text-align,line-heighttext-decoration(underline, line-through)text-shadow(offset-x, offset-y, blur-radius, color)@font-facedeclarations with full weight and style matching
Font Loading
html2pic supports multiple ways to load custom fonts with proper fallback support:
@font-face Support (Recommended)
/* Define custom fonts with @font-face */
@font-face {
font-family: "MyCustomFont";
src: url("./fonts/custom-font.ttf");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "MyCustomFont";
src: url("./fonts/custom-font-bold.ttf");
font-weight: bold;
font-style: normal;
}
/* Use with fallbacks */
h1 {
font-family: "MyCustomFont", Arial, sans-serif;
font-weight: bold;
}
Direct Font File References
/* System font */
font-family: "Arial", sans-serif;
/* Custom font file (provide absolute or relative path) */
font-family: "/path/to/custom-font.ttf";
/* Multiple fallbacks */
font-family: "Custom Font", "Arial", sans-serif;
Features:
- @font-face declarations: Full CSS @font-face support with font-family, src, font-weight, and font-style
- Font fallbacks: Automatic fallback chain resolution - @font-face fonts are prioritized, then system fonts. Font fallbacks are only used for not supported glyphs in the previous font, but the provided fonts must exist.
- Weight and style matching: Different font files for different weights (normal, bold) and styles (normal, italic)
- Flexible paths: Support for relative paths, absolute paths, and URLs in src property
- PicTex integration: Uses PicTex's
font_fallbacks()function for optimal font rendering
Note: When using @font-face, provide paths to font files (.ttf, .otf, .woff2). If a font cannot be loaded, the system automatically falls back to the next font in the fallback chain.
Linear Gradients
html2pic supports CSS linear-gradient syntax for backgrounds:
/* Angle-based gradients */
background-image: linear-gradient(135deg, #667eea, #764ba2);
/* Direction keywords */
background-image: linear-gradient(to right, red, blue);
/* Color stops with percentages */
background-image: linear-gradient(90deg, #ff0000 0%, #00ff00 50%, #0000ff 100%);
/* Multiple colors */
background-image: linear-gradient(45deg, yellow, orange, red, purple);
Supported features:
- Angle directions (0deg, 45deg, 135deg, etc.)
- Keyword directions (to right, to bottom, to top left, etc.)
- Color stops with percentages
- Multiple colors with automatic distribution
- All CSS color formats (hex, rgb, rgba, named colors)
Limitations: Only linear gradients are supported. Radial and conic gradients are not yet implemented.
CSS Positioning
position: absolutewithleftandtopproperties (px, %, em, rem)- Limitation: Only
leftandtopare supported, notrightorbottom
CSS At-Rules
@font-facedeclarations for custom font loading
CSS Selectors
- Tag selectors:
div,p,h1 - Class selectors:
.my-class - ID selectors:
#my-id - Universal selector:
*
📝 Examples
Explore the examples/ folder for complete runnable examples with generated output images.
Quick Start Example
Basic card layout demonstrating core html2pic functionality:
from html2pic import Html2Pic
html = '''
<div class="card">
<h1>Hello, World!</h1>
<p class="subtitle">Generated with html2pic</p>
</div>
'''
css = '''
.card {
display: flex;
flex-direction: column;
align-items: center;
padding: 30px;
background-color: #f0f8ff;
border-radius: 15px;
width: 300px;
}
h1 {
color: #2c3e50;
font-size: 28px;
margin: 0 0 10px 0;
}
.subtitle {
color: #7f8c8d;
font-size: 16px;
margin: 0;
}
'''
renderer = Html2Pic(html, css)
image = renderer.render()
image.save("output.png")
Individual Border-Radius Properties
Showcase different corner radius values:
html = '''
<div class="card-container">
<div class="rounded-card">Individual Corner Radii</div>
</div>
'''
css = '''
.card-container {
padding: 20px;
background-color: #f5f5f5;
}
.rounded-card {
width: 300px;
height: 150px;
background-color: #e1f5fe;
padding: 20px;
border: 3px solid #0277bd;
/* Individual corner border-radius properties */
border-top-left-radius: 5px;
border-top-right-radius: 20px;
border-bottom-right-radius: 40px;
border-bottom-left-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
color: #01579b;
}
'''
renderer = Html2Pic(html, css)
image = renderer.render()
image.save("border_radius_example.png")
Alpha Channel Colors and Display None
Advanced styling with transparency and hidden elements:
html = '''
<div class="container">
<div class="visible-card">Visible Card</div>
<div class="hidden-card">This won't appear</div>
<div class="transparent-card">Semi-transparent Card</div>
</div>
'''
css = '''
.container {
display: flex;
flex-direction: column;
gap: 15px;
padding: 20px;
}
.visible-card {
background-color: rgba(76, 175, 80, 0.9);
padding: 15px;
border-radius: 8px;
color: white;
}
.hidden-card {
background-color: red;
padding: 15px;
display: none; /* This element won't be rendered at all */
}
.transparent-card {
background-color: rgba(33, 150, 243, 0.3); /* Semi-transparent blue */
padding: 15px;
border-radius: 8px;
border: 2px solid rgba(33, 150, 243, 0.8);
}
'''
renderer = Html2Pic(html, css)
image = renderer.render()
image.save("advanced_styling_example.png")
Flexbox Card Layout
Social media style user card with horizontal layout:
html = '''
<div class="user-card">
<div class="avatar"></div>
<div class="user-info">
<h2>Alex Doe</h2>
<p>@alexdoe</p>
</div>
</div>
'''
css = '''
.user-card {
display: flex;
align-items: center;
gap: 15px;
padding: 20px;
background-color: white;
border-radius: 12px;
border: 1px solid #e1e8ed;
}
.avatar {
width: 60px;
height: 60px;
background-color: #1da1f2;
border-radius: 50%;
}
.user-info h2 {
margin: 0 0 4px 0;
font-size: 18px;
color: #14171a;
}
.user-info p {
margin: 0;
color: #657786;
font-size: 14px;
}
'''
Advanced Visual Effects
Shadows, positioning, and advanced styling features:
Background Images
Background image support with different sizing modes:
Complete examples with full source code are available in the examples/ directory.
🔧 API Reference
Html2Pic Class
Html2Pic(html: str, css: str = "", base_font_size: int = 16)
Methods:
render(crop_mode=CropMode.SMART) -> BitmapImage: Render to raster imagerender_as_svg(embed_font=True) -> VectorImage: Render to SVGdebug_info() -> dict: Get debugging information about parsing and styling
Output Objects
The rendered images are PicTex BitmapImage or VectorImage objects with methods like:
save(filename): Save to fileto_numpy(): Convert to NumPy arrayto_pillow(): Convert to PIL Imageshow(): Display the image
🚧 Current Limitations
This is an early version focusing on core functionality. A lot of features are not yet supported.
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Built on top of PicTex for high-quality rendering
- Uses BeautifulSoup for HTML parsing
- Uses tinycss2 for CSS parsing
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file html2pic-0.1.3.tar.gz.
File metadata
- Download URL: html2pic-0.1.3.tar.gz
- Upload date:
- Size: 936.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3a478ea3a8a33844e0baba064ce08bf8721f7ad04d8a9f3f30626d8e9cf25a2
|
|
| MD5 |
3bd98beb2deb37fcb6d15f47443f4a02
|
|
| BLAKE2b-256 |
0855890ec7ef39be2fff6d5a47359d76c04fca8780b3220af1d85602a36f6a70
|
File details
Details for the file html2pic-0.1.3-py3-none-any.whl.
File metadata
- Download URL: html2pic-0.1.3-py3-none-any.whl
- Upload date:
- Size: 35.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd662d98da45273f84a7f39dae7518375c72cd964318f73adbcd0574d75e179a
|
|
| MD5 |
d3a3f3177e79c21b2f5804302f62be36
|
|
| BLAKE2b-256 |
85b2c6b512be8ec46e6990e9ff80e7702d0b0f4a9050da5bb55885ea251a0374
|