Menu
Załóż konto
API HTML do obrazka

HTML na obrazek: twój HTML i CSS jako PNG z prawdziwego Chrome

API „HTML na obrazek” składa twój kod i CSS w przeglądarce i oddaje zdjęcie wyniku. W Shareglint zapisujesz HTML i CSS raz, jako szablon; potem każdy obrazek to jedno żądanie HTTP — POST /v1/images z nazwą szablonu i tekstem, który się zmienia — a w odpowiedzi dostajesz adres pliku PNG, JPEG, WebP albo PDF, zwykle po około sekundzie.

To prawdziwy Chrome, a nie odtworzony CSS: grid, flexbox, gradienty, cienie, emoji i tekst od prawej do lewej wychodzą tak jak w twojej przeglądarce. Wypróbuj to niżej, bez zakładania konta.

Wypróbuj: HTML i CSS do PNG, bez konta

Zmień HTML i CSS, potem wyrenderuj. Dostaniesz PNG 1200×630 z tego samego Chrome, który renderuje obrazki z API.

Podgląd pozwala na 5 renderów na godzinę z jednego adresu i dodaje znak wodny planu Free. Skrypty, formularze, ramki iframe i SVG są usuwane, tak samo jak każdy zewnętrzny adres — obrazki i fonty z innych serwerów się nie wczytają (adresy data: tak). Te same zasady obowiązują zapisane szablony.

Jak to działa w API

Dwa wywołania na start, potem jedno na każdy obrazek.

  1. Zapisz szablon raz. POST /v1/templates z twoim HTML-em, CSS-em, wymiarami i nazwami pól, które się zmieniają. Pola wstawiasz do HTML-a jako {{ nazwa }}; HTML jest czyszczony przy zapisie.
  2. Wyrenderuj obrazek. POST /v1/images ze slugiem szablonu, wartościami pól i formatem. Z ?wait=true adres gotowego pliku wraca na tym samym połączeniu.
  3. Użyj adresu. W og:image, w mailu, w feedzie albo do pobrania. Te same pola drugi raz zwracają istniejący plik i nie zużywają limitu.

Podczas projektowania POST /v1/templates/preview renderuje szkic bez zapisywania i nie zużywa limitu.

Kod: curl, JavaScript, PHP i Python

Każdy przykład zapisuje szablon i renderuje jeden PNG. Zamień sk_live_YOUR_KEY na swój klucz z panelu.

curl

# 1. Save the template once
curl -X POST "https://shareglint.com/v1/templates" \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Article card",
  "width": 1200,
  "height": 630,
  "fields": [
    "kicker",
    "title",
    "author"
  ],
  "html": "<div class=\"card\"><p class=\"kicker\">{{ kicker }}</p><div class=\"fitbox\"><h1 class=\"fit\" data-autofit>{{ title }}</h1></div><p class=\"by\">{{ author }}</p></div>",
  "css": ".card{height:100%;padding:72px;display:grid;grid-template-rows:auto 1fr auto;gap:24px;background:#0f172a;color:#f8fafc;font-family:Roboto,sans-serif} .kicker{color:#fbbf24;font-size:26px;letter-spacing:.1em;text-transform:uppercase} h1{font-size:76px;line-height:1.08} .by{font-size:28px;color:#94a3b8}"
}'
# → {"id": "tpl_…", "slug": "article-card", …}

# 2. One call per image (use the slug from step 1)
curl -X POST "https://shareglint.com/v1/images?wait=true" \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "template": "article-card",
  "format": "png",
  "modifications": {
    "kicker": "Engineering",
    "title": "How we cut our build time in half",
    "author": "Ada Lovelace"
  }
}'

JavaScript

const API = 'https://shareglint.com/v1';
const headers = {
  Authorization: 'Bearer sk_live_YOUR_KEY',
  'Content-Type': 'application/json',
};

// 1. Save the template once
const template = await fetch(`${API}/templates`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    name: "Article card",
    width: 1200,
    height: 630,
    fields: ['kicker', 'title', 'author'],
    html: "<div class=\"card\"><p class=\"kicker\">{{ kicker }}</p><div class=\"fitbox\"><h1 class=\"fit\" data-autofit>{{ title }}</h1></div><p class=\"by\">{{ author }}</p></div>",
    css: ".card{height:100%;padding:72px;display:grid;grid-template-rows:auto 1fr auto;gap:24px;background:#0f172a;color:#f8fafc;font-family:Roboto,sans-serif} .kicker{color:#fbbf24;font-size:26px;letter-spacing:.1em;text-transform:uppercase} h1{font-size:76px;line-height:1.08} .by{font-size:28px;color:#94a3b8}",
  }),
}).then((r) => r.json());

// 2. One call per image
const image = await fetch(`${API}/images?wait=true`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    template: template.slug,
    format: 'png',
    modifications: {
      kicker: "Engineering",
      title: "How we cut our build time in half",
      author: "Ada Lovelace",
    },
  }),
}).then((r) => r.json());

console.log(image.url);

PHP (Laravel)

use Illuminate\Support\Facades\Http;

$api = Http::withToken('sk_live_YOUR_KEY')->baseUrl('https://shareglint.com/v1');

// 1. Save the template once
$template = $api->post('/templates', [
    'name' => 'Article card',
    'width' => 1200,
    'height' => 630,
    'fields' => ['kicker', 'title', 'author'],
    'html' => '<div class="card"><p class="kicker">{{ kicker }}</p><div class="fitbox"><h1 class="fit" data-autofit>{{ title }}</h1></div><p class="by">{{ author }}</p></div>',
    'css' => '.card{height:100%;padding:72px;display:grid;grid-template-rows:auto 1fr auto;gap:24px;background:#0f172a;color:#f8fafc;font-family:Roboto,sans-serif} .kicker{color:#fbbf24;font-size:26px;letter-spacing:.1em;text-transform:uppercase} h1{font-size:76px;line-height:1.08} .by{font-size:28px;color:#94a3b8}',
])->json();

// 2. One call per image
$image = $api->post('/images?wait=true', [
    'template' => $template['slug'],
    'format' => 'png',
    'modifications' => [
        'kicker' => 'Engineering',
        'title' => 'How we cut our build time in half',
        'author' => 'Ada Lovelace',
    ],
])->json();

echo $image['url'];

Python

import requests

API = "https://shareglint.com/v1"
HEADERS = {"Authorization": "Bearer sk_live_YOUR_KEY"}

# 1. Save the template once
template = requests.post(f"{API}/templates", headers=HEADERS, json={
    "name": "Article card",
    "width": 1200,
    "height": 630,
    "fields": ["kicker", "title", "author"],
    "html": "<div class=\"card\"><p class=\"kicker\">{{ kicker }}</p><div class=\"fitbox\"><h1 class=\"fit\" data-autofit>{{ title }}</h1></div><p class=\"by\">{{ author }}</p></div>",
    "css": ".card{height:100%;padding:72px;display:grid;grid-template-rows:auto 1fr auto;gap:24px;background:#0f172a;color:#f8fafc;font-family:Roboto,sans-serif} .kicker{color:#fbbf24;font-size:26px;letter-spacing:.1em;text-transform:uppercase} h1{font-size:76px;line-height:1.08} .by{font-size:28px;color:#94a3b8}",
}).json()

# 2. One call per image
image = requests.post(f"{API}/images?wait=true", headers=HEADERS, json={
    "template": template["slug"],
    "format": "png",
    "modifications": {
        "kicker": "Engineering",
        "title": "How we cut our build time in half",
        "author": "Ada Lovelace",
    },
}).json()

print(image["url"])

Co wraca

{
    "id": "img_01m08s3ez1zcv28h335g9923bw",
    "kind": "image",
    "status": "completed",
    "format": "png",
    "size": "og",
    "width": 1200,
    "height": 630,
    "url": "https://cdn.shareglint.com/renders/img_01m08s3ez1zcv28h335g9923bw.png",
    "duration_ms": 912
}

Formaty wyjściowe

formatCo dostajesz
png Bezstratny. scale 2 (domyślnie) podwaja piksele: szablon 1200×630 daje plik 2400×1260; scale 1 daje dokładnie 1200×630.
jpeg Mniejsze pliki przy zdjęciach; jakość od 1 do 100, domyślnie 85.
webp Jeszcze mniejsze, z tym samym ustawieniem jakości co JPEG.
pdf Jedna strona dokładnie w rozmiarze szablonu, z tłami, tekst zostaje wektorowy i da się go zaznaczyć.
gif, mp4 Animacja: nagrywa animacje CSS szablonu, do 5 sekund; każdy kosztuje 5 renderów z limitu.

Jeden szablon renderuje się też w każdym gotowym rozmiarze (og 1200×630, square 1080×1080, portrait 1080×1350, story 1080×1920, pinterest 1000×1500, youtube 1280×720) — jaki rozmiar chce każda platforma.

Dlaczego prawdziwy Chrome, a nie biblioteka

Są trzy popularne sposoby, żeby samemu zamienić HTML na obrazek. Każdy działa; każdy ma koszt, który wychodzi później.

SposóbJaki CSS renderujeCo bierzesz na siebie
Satori / @vercel/og Podzbiór: JSX z układem flexbox, bez CSS grid Kartę piszesz w JSX, pliki fontów ładujesz sam, a całość chodzi w twojej funkcji Next.js albo edge
wkhtmltoimage Stary silnik Qt WebKit: bez CSS grid, nowoczesny CSS zawodny Narzędzie, którego projekt zarchiwizowano w 2023 roku, zainstalowane na twoich serwerach
Puppeteer albo Playwright na twoich serwerach Wszystko, co renderuje Chrome Pamięć i awarie Chrome, fonty na każdej maszynie, kolejka i izolowanie HTML-a, którego nie napisałeś
Shareglint Wszystko, co renderuje Chrome Jedno żądanie HTTP; Chrome, fonty, piaskownica, cache i przechowywanie są po naszej stronie

Jeśli strona stoi na Next.js, a karta mieści się we flexboksie, @vercel/og jest darmowy i działa tuż obok twoich stron — bierz go. Własny Chrome ma sens, gdy już go utrzymujesz na dużą skalę. API opłaca się wtedy, gdy nie chcesz robić ani jednego, ani drugiego.

Ograniczenia, wprost

Ile to kosztuje

Free: 100 obrazków miesięcznie, bez karty, z małym znakiem wodnym. Starter: $9 miesięcznie za 2,000 obrazków ($4.50 za tysiąc), bez znaku wodnego. Render, który już masz — ten sam szablon, te same pola, ten sam format — wraca z cache i nie zużywa limitu.

Pytania

Czym jest API „HTML na obrazek”?

Usługą sieciową, która bierze HTML i CSS, składa je w silniku przeglądarki i zwraca obraz wyniku — PNG, JPEG, WebP albo PDF. Przydaje się, gdy obrazek ma powstawać z danych: karty do mediów społecznościowych, certyfikaty, rachunki, wykresy z podpisami, banery do maili.

Jak zamienić HTML na PNG przez API?

W Shareglint: zapisz HTML i CSS raz przez POST /v1/templates, potem wywołaj POST /v1/images?wait=true ze slugiem szablonu, wartościami pól i "format": "png". Odpowiedź zawiera adres PNG.

Czy mogę zamienić HTML na PDF?

Tak. "format": "pdf" zwraca jedną stronę dokładnie w rozmiarze szablonu, z wydrukowanymi tłami i tekstem w wektorze, więc zostaje ostry i da się go zaznaczyć.

Czy działa CSS grid, flexbox i własne fonty?

Grid, flexbox i reszta nowoczesnego CSS-a działają, bo rendererem jest Chrome. Fonty pochodzą z rodzin zainstalowanych w rendererze (Roboto, Open Sans, Carlito, DejaVu Sans, DejaVu Serif, DejaVu Sans Mono, Ubuntu, Noto Sans CJK JP, Noto Sans CJK SC, Noto Color Emoji); wgrywania własnych plików fontów nie ma.

Czy HTML może uruchamiać JavaScript?

Nie. Szablony są czyszczone przy zapisie i skrypty znikają — dzięki temu można bezpiecznie renderować HTML od kogokolwiek. Stronę, która potrzebuje swoich skryptów, zrzucisz przez Screenshot API z jej adresu.

Czy jest darmowe API do zamiany HTML na obrazek?

Plan Free renderuje 100 obrazków miesięcznie bez karty, z małym znakiem wodnym. Podgląd na tej stronie nie wymaga nawet konta.

Czym to się różni od HTMLCSStoImage?

HTMLCSStoImage przyjmuje cały HTML w każdym żądaniu. Shareglint przechowuje szablon raz i przyjmuje tylko zmieniające się pola, dopasowuje długość tekstu, ma cache, który nie zużywa limitu, i 153 gotowych szablonów. Jeśli twój HTML jest za każdym razem inny, ich model pasuje lepiej.