{"id":30239869,"url":"https://github.com/francozanardi/pictex","last_synced_at":"2026-04-02T17:51:24.016Z","repository":{"id":303890763,"uuid":"1016886346","full_name":"francozanardi/pictex","owner":"francozanardi","description":"A Python library for efficient image generation using CSS Flexbox","archived":false,"fork":false,"pushed_at":"2026-03-23T23:33:29.000Z","size":17753,"stargazers_count":197,"open_issues_count":6,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-03-24T13:14:21.292Z","etag":null,"topics":["flexbox","flexbox-css","gradient","graphics","image-generation","python","shadow","skia","taffy","text-rendering","text-to-image","typography"],"latest_commit_sha":null,"homepage":"https://pictex.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/francozanardi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-09T17:17:27.000Z","updated_at":"2026-03-23T23:30:13.000Z","dependencies_parsed_at":"2026-03-23T19:02:17.122Z","dependency_job_id":null,"html_url":"https://github.com/francozanardi/pictex","commit_stats":null,"previous_names":["francozanardi/pictex"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/francozanardi/pictex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francozanardi%2Fpictex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francozanardi%2Fpictex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francozanardi%2Fpictex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francozanardi%2Fpictex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/francozanardi","download_url":"https://codeload.github.com/francozanardi/pictex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francozanardi%2Fpictex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31312744,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flexbox","flexbox-css","gradient","graphics","image-generation","python","shadow","skia","taffy","text-rendering","text-to-image","typography"],"created_at":"2025-08-15T04:02:42.160Z","updated_at":"2026-04-02T17:51:24.009Z","avatar_url":"https://github.com/francozanardi.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# PicTex\n\n[![PyPI version](https://badge.fury.io/py/pictex.svg?v=5)](https://pypi.org/project/pictex/)\n[![CI Status](https://github.com/francozanardi/pictex/actions/workflows/ci.yml/badge.svg)](https://github.com/francozanardi/pictex/actions/workflows/ci.yml)\n[![Codecov](https://codecov.io/gh/francozanardi/pictex/branch/main/graph/badge.svg)](https://codecov.io/gh/francozanardi/pictex)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nProgrammatically generate high-quality images using standard CSS Flexbox layouts. Powered by Skia, Taffy and HarfBuzz.\n\n![PicTex](https://res.cloudinary.com/dlvnbnb9v/image/upload/v1753831765/readme-1_vqnohh.png)\n\nA Python library for efficient image generation using CSS Flexbox. Build complex layouts using familiar web standards, such as `justify-content`, `align-items`, `flex-grow`, then render them as high-quality PNG, JPEG, WebP, or SVG. Perfect for Open Graph, social media graphics, video thumbnails, data visualizations, and automated report generation. Browser-grade layouts without the browser overhead\n\n## Features\n\n-   **CSS Flexbox Layout**: Built on industry-standard CSS Flexbox principles with near-complete property support. If you know CSS, you know PicTex. See the [CSS Flexbox Compliance](#css-flexbox-compliance) table below. Powered by **Taffy** layout engine (via `stretchable`).\n-   **Component-Based Design**: Compose complex visuals by nesting powerful layout primitives like `Row`, `Column`, and `Image`.\n-   **Rich Styling**: Gradients, multiple shadows, borders with rounded corners, and text decorations.\n-   **Advanced Typography**: Custom fonts, variable fonts, line height, alignment, and professional text shaping using **HarfBuzz** for kerning, ligatures, and complex scripts.\n-   **Automatic Font Fallback**: Seamlessly render emojis and multilingual text.\n-   **Bidirectional Text (BiDi)**: Automatic Unicode BiDi algorithm for proper LTR/RTL mixed text rendering.\n-   **Flexible Output**: \n    -   **Raster**: Save as PNG/JPEG/WebP, or convert to NumPy/Pillow.\n    -   **Vector**: Export to a clean, scalable SVG file with font embedding.\n-   **High-Quality Rendering**: Powered by Google's **Skia** graphics engine (via `skia-python`).\n\n\u003e [!IMPORTANT]\n\u003e **Upgrading from v1.x?** PicTex v2.0 introduces significant changes to the layout and positioning system. Please read the [Migration Guide](docs/MIGRATION.md) to update your code.\n\n## Installation\n\nIt is highly recommended to install PicTex in a virtual environment to avoid conflicts with system-wide packages and potential permission issues on certain operating systems like Windows.\n\n```bash\n# 1. Create and activate a virtual environment\npython -m venv .venv\n\n# On Windows:\n.\\.venv\\Scripts\\activate\n\n# On macOS/Linux:\n# source .venv/bin/activate\n\n# 2. Install PicTex into the active environment\npip install pictex\n```\n\n## Quickstart\n\n### Styled text image\n\nCreating a stylized text image is as simple as building a `Canvas` and calling `.render()`.\n\n```python\nfrom pictex import Canvas, Shadow, LinearGradient\n\n# 1. Create a style template using the fluent API\ncanvas = (\n    Canvas()\n    .font_family(\"Poppins-Bold.ttf\")\n    .font_size(60)\n    .color(\"white\")\n    .padding(20)\n    .background_color(LinearGradient([\"#2C3E50\", \"#FD746C\"]))\n    .border_radius(10)\n    .text_shadows(Shadow(offset=(2, 2), blur_radius=3, color=\"black\"))\n)\n\n# 2. Render some text using the template\nimage = canvas.render(\"Hello, World! 🎨✨\")\n\n# 3. Save or show the result\nimage.save(\"hello.png\")\n```\n\n![Quickstart result](https://res.cloudinary.com/dlvnbnb9v/image/upload/v1754103059/hello_zqkkba.png)\n\n### Composed elements\n\nCompose elements like `Row`, `Column`, and `Text` to build complex visuals. PicTex's fluent API makes styling declarative and intuitive.\n\n```python\nfrom pictex import *\n\n# 1. Build your visual components\navatar = (\n    Image(\"avatar.png\")\n    .border_radius(\"50%\")\n    .background_color(\"silver\")\n    .border(3, \"white\")\n    .box_shadows(Shadow(offset=(2, 2), blur_radius=5, color=\"black\"))\n)\n\nuser_info = Column(\n    Text(\"Alex Doe\").font_size(24).font_weight(700).color(\"#184e77\"),\n    Text(\"Graphic Designer\").color(\"#edf6f9\").text_shadows(Shadow(offset=(1, 1), blur_radius=1, color=\"black\")),\n).align_items(\"center\").gap(4)\n\n# 2. Compose them in a layout container\ncard = (\n    Column(avatar, user_info)\n    .background_color(LinearGradient([\"#d9ed92\", \"#52b69a\"]))\n    .border_radius(20)\n    .padding(30)\n    .align_items(\"center\")\n    .gap(20)\n)\n\n# 3. Render and save the final image\ncanvas = Canvas().font_family(\"NataSans.ttf\")\nimage = canvas.render(card)\nimage.save(\"profile_card.png\")\n```\n\n![Quickstart result](https://res.cloudinary.com/dlvnbnb9v/image/upload/v1754103067/profile_card_b7ofk7.png)\n\n## More Examples\n\n| Preview                                                      | Description                                                                                                                                                                                                                    |\n|:-------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| ![GitHub Card Example](https://res.cloudinary.com/dlvnbnb9v/image/upload/v1774751560/github_card_imhh6z.png)   | **GitHub Repository Card** \u003cbr/\u003e Generate beautiful cards for any GitHub repo. Just change the repo name and it fetches real data from the API. \u003cbr/\u003e **[View Code »](https://github.com/francozanardi/pictex/blob/main/examples/github_card/github_card.py)**    |\n| ![Tweet to Image Example](https://res.cloudinary.com/dlvnbnb9v/image/upload/v1774751651/tweet_vwhhev.png)   | **Tweet to Image** \u003cbr/\u003e Recreate the look and feel of a tweet, perfect for sharing on other social platforms. \u003cbr/\u003e **[View Code »](https://github.com/francozanardi/pictex/blob/main/examples/tweet_card/tweet_card.py)**    |\n| ![Data Table Example](https://res.cloudinary.com/dlvnbnb9v/image/upload/v1774751657/table_vj3fwk.png)            | **Data Table** \u003cbr/\u003e Generate a clean, styled table from a 2D list. Includes headers, zebra-striping, and shadows. \u003cbr/\u003e **[View Code »](https://github.com/francozanardi/pictex/blob/main/examples/table/table.py)**          |\n| ![Code Snippet Example](https://res.cloudinary.com/dlvnbnb9v/image/upload/v1774751662/result_deh3fj.png) | **Code Snippet** \u003cbr/\u003e Create beautifully syntax-highlighted images of your code snippets for tutorials or social media. \u003cbr/\u003e **[View Code »](https://github.com/francozanardi/pictex/blob/main/examples/code_to_image/code_to_image.py)** |\n\nCheck out the full [examples](https://github.com/francozanardi/pictex/tree/main/examples) directory for more!\n\n## CSS Flexbox Compliance\n\nPicTex v2.0 implements CSS Flexbox layout with high fidelity. If you're familiar with CSS, you'll feel right at home. Here's our compliance status:\n\n### Container Properties\n\n| CSS Property | Status | PicTex Method | Notes |\n|--------------|--------|---------------|-------|\n| `display: flex` | ✅ | `Row()` / `Column()` | Implicit in layout containers |\n| `flex-direction` | ✅ | `Row()` / `Column()` | `Row` = row, `Column` = column |\n| `flex-wrap` | ✅ | `.flex_wrap()` | `nowrap`, `wrap`, `wrap-reverse` |\n| `flex-flow` | ⚠️ | N/A | Shorthand for flex-direction + flex-wrap |\n| `justify-content` | ✅ | `.justify_content()` | All standard values supported |\n| `align-items` | ✅ | `.align_items()` | All standard values supported |\n| `align-content` | ⚠️ | Not yet | Planned for multi-line flex containers |\n| `gap` | ✅ | `.gap()` | Unified gap (not split into row-gap/column-gap) |\n| `direction` | ✅ | `.direction()` | Supports `ltr` and `rtl` with inheritance |\n\n### Item Properties\n\n|  CSS Property | Status | PicTex Method | Notes |\n|--------------|--------|---------------|-------|\n| `flex` | ⚠️ | N/A | Shorthand for flex-grow + flex-shrink + flex-basis |\n| `flex-grow` | ✅ | `.flex_grow()` | Control growth behavior |\n| `flex-shrink` | ✅ | `.flex_shrink()` | Control shrink behavior |\n| `flex-basis` | ⚠️ | Not yet | Can use `.size()` as alternative |\n| `align-self` | ✅ | `.align_self()` | Override container alignment |\n| `order` | ❌ | Not planned | Less relevant for static image generation |\n\n### Positioning \u0026 Sizing\n\n| CSS Property | Status | PicTex Method | Notes |\n|--------------|--------|---------------|-------|\n| `position` | ✅ | `.absolute_position()` / `.relative_position()` | Full CSS positioning support |\n| `top` / `right` / `bottom` / `left` | ✅ | `.absolute_position(top=, right=, ...)` | CSS insets |\n| `width` / `height` | ✅ | `.size()` | Pixels, percentages, auto, fit-content |\n| `min-width` / `max-width` | ✅ | `.min_width()` / `.max_width()` | Prevent collapse/overflow |\n| `min-height` / `max-height` | ✅ | `.min_height()` / `.max_height()` | Prevent collapse/overflow |\n| `aspect-ratio` | ✅ | `.aspect_ratio()` | Maintain proportions |\n| `transform: translate()` | ✅ | `.translate()` | Post-layout transforms |\n\n**Legend**: ✅ Fully supported | ⚠️ Planned | ❌ Not planned\n\nThis compliance makes PicTex an excellent choice for developers who want to apply their CSS knowledge to generate images programmatically.\n\n## 📚 Dive Deeper\n\nFor a complete guide on all features, from layout and the box model to advanced styling, check out our full documentation:\n\n-   [**Getting Started**](https://pictex.readthedocs.io/en/latest/getting_started/)\n-   [**Core Concepts**](https://pictex.readthedocs.io/en/latest/core_concepts/)\n-   [**Styling Guide: The Box Model**](https://pictex.readthedocs.io/en/latest/box_model/)\n-   [**Styling Guide: Colors \u0026 Gradients**](https://pictex.readthedocs.io/en/latest/colors/)\n-   [**Styling Guide: Text \u0026 Fonts**](https://pictex.readthedocs.io/en/latest/text/)\n\n## Troubleshooting\n\n### Text rendering issues on Windows (missing ligatures, incorrect text shaping)\n\n**Symptom:** You may notice that advanced typography features, such as font ligatures or complex scripts, do not render correctly on Windows.\n\n**Cause:** This is typically caused by an incomplete installation of the `skia-python` dependency, where a crucial data file (`icudtl.dat`) required for advanced text shaping is missing. This often happens when `pip` installs the package in a user-level directory without administrator privileges.\n\n**Solutions:**\n\n1.  **(Recommended) Reinstall in a Virtual Environment:** This is the safest and most reliable method to ensure a correct installation. A virtual environment does not require administrator rights and provides a clean slate.\n\n    ```bash\n    # If already installed, uninstall first\n    pip uninstall pictex skia-python\n\n    # Create and activate a new virtual environment (see installation section)\n    python -m venv .venv\n    .\\.venv\\Scripts\\activate\n\n    # Install PicTex again\n    pip install pictex\n    ```\n\n2.  **Reinstall with Administrator Privileges:** If you cannot use a virtual environment, running the installation from a terminal with administrator rights will allow `pip` to install the package correctly.\n\n    ```bash\n    # Open PowerShell or Command Prompt as an Administrator\n    pip install --force-reinstall pictex\n    ```\n\n## Contributing\n\nContributions, issues, and feature requests are welcome! Feel free to check the [issues page](https://github.com/francozanardi/pictex/issues).\n\n## Running tests locally (matching CI environment)\n\n```bash\ndocker build -f Dockerfile.test -t pictex-test .\ndocker run --rm -v \"$(pwd):/app\" pictex-test pytest\n```\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](https://github.com/francozanardi/pictex/LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrancozanardi%2Fpictex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrancozanardi%2Fpictex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrancozanardi%2Fpictex/lists"}