# API obrázků a hostitel obrázků

> Endpointy obrázků vypisují plakáty, pozadí, loga, profily a záběry titulu jako cesty k souborům. Každý soubor pak načtete z img.amodb.dev v pevné velikosti, bez klíče a s cache na edge na 30 dní. Cesty a JSON odpovídají TMDB v3, takže stávající kód pro obrázky funguje po změně základní URL.

## Endpoint

`GET /3/movie/{movie_id}/images`

```bash
curl "https://api.amodb.dev/3/movie/550/images?include_image_language=en,null" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Odpověď:

```json
{
  "id": 550,
  "backdrops": [
    {
      "aspect_ratio": 1.778,
      "height": 1440,
      "iso_639_1": null,
      "file_path": "/c6OLXfKAk5BKeR6broC8pYiCquX.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 2560
    },
    {
      "aspect_ratio": 1.778,
      "height": 1080,
      "iso_639_1": "en",
      "file_path": "/b9HyPoxwxjxkWEUL5ErZdhApQe2.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1920
    },
    {
      "aspect_ratio": 1.778,
      "height": 2160,
      "iso_639_1": "en",
      "file_path": "/ewMhHVyXQKMAviVWM7InPjZqpSr.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 3840
    }
  ],
  "logos": [
    {
      "aspect_ratio": 4.638,
      "height": 389,
      "iso_639_1": "en",
      "file_path": "/7Uqhv24pGJs4Ns31NoOPWFJGWNG.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1804
    },
    {
      "aspect_ratio": 0.848,
      "height": 1295,
      "iso_639_1": "en",
      "file_path": "/4XkF0Rf7gvSfea8fYLFbU5tmuJw.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1098
    },
    {
      "aspect_ratio": 1.457,
      "height": 1299,
      "iso_639_1": "en",
      "file_path": "/lm0VCzO1ZFhyx81k5Fzkex4u6C8.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1893
    }
  ],
  "posters": [
    {
      "aspect_ratio": 0.667,
      "height": 3000,
      "iso_639_1": "en",
      "file_path": "/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 2000
    },
    {
      "aspect_ratio": 0,
      "height": 0,
      "iso_639_1": null,
      "file_path": "/qkrH7rjYKU4KOwwIl6wF6H3ISvm.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 0
    },
    {
      "aspect_ratio": 0,
      "height": 0,
      "iso_639_1": null,
      "file_path": "/efBb4gjjKneUoBVgfFOUu2OwihS.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 0
    }
  ]
}
```

## Získání obrázků filmu

`GET /3/movie/{movie_id}/images` vypíše všechny známé obrázky jednoho filmu jako tři pole: `backdrops`, `logos` a `posters`. Každá položka má `file_path`, rozměry v pixelech a jazykový tag. Samotný soubor v JSON není. Načtete jej z hostitele obrázků druhým krokem.

Příklad si vyžádá anglické obrázky a obrázky bez textu, vybere první anglický plakát a pak načte tento soubor o šířce 500 pixelů.

```bash
curl -s "https://api.amodb.dev/3/movie/550/images?include_image_language=en,null" \
  -H "Authorization: Bearer $AMODB_KEY"

curl -s -o poster.jpg -w "%{http_code}\n" \
  "https://img.amodb.dev/t/p/w500/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg"
```

```js
const url = 'https://api.amodb.dev/3/movie/550/images?include_image_language=en,null';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { posters } = await res.json();
if (posters.length === 0) throw new Error('no posters');
const poster = posters.find((p) => p.iso_639_1 === 'en') ?? posters[0];
const posterUrl = `https://img.amodb.dev/t/p/w500${poster.file_path}`;
const img = await fetch(posterUrl);
console.log(img.status, img.headers.get('content-type'), posterUrl);
```

```python
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/movie/550/images",
    params={"include_image_language": "en,null"},
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
posters = r.json()["posters"]
if not posters:
    raise SystemExit("no posters")
poster = next((p for p in posters if p["iso_639_1"] == "en"), posters[0])
poster_url = "https://img.amodb.dev/t/p/w500" + poster["file_path"]
img = requests.get(poster_url, timeout=10)
print(img.status_code, img.headers.get("content-type"), poster_url)
```

```php
<?php
$url = 'https://api.amodb.dev/3/movie/550/images?include_image_language=en,null';
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
    throw new RuntimeException("amodb returned $status");
}
$posters = json_decode($body, true)['posters'];
if (!$posters) {
    throw new RuntimeException('no posters');
}
$poster = $posters[0];
foreach ($posters as $p) {
    if ($p['iso_639_1'] === 'en') {
        $poster = $p;
        break;
    }
}
$posterUrl = 'https://img.amodb.dev/t/p/w500' . $poster['file_path'];
$img = curl_init($posterUrl);
curl_setopt_array($img, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10]);
curl_exec($img);
echo curl_getinfo($img, CURLINFO_HTTP_CODE), ' ', curl_getinfo($img, CURLINFO_CONTENT_TYPE), ' ', $posterUrl, PHP_EOL;
curl_close($img);
```

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

type Images struct {
	Posters []struct {
		FilePath string `json:"file_path"`
		Language string `json:"iso_639_1"`
	} `json:"posters"`
}

func main() {
	url := "https://api.amodb.dev/3/movie/550/images?include_image_language=en,null"
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	client := &http.Client{Timeout: 10 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		panic(res.Status)
	}
	var images Images
	if err := json.NewDecoder(res.Body).Decode(&images); err != nil || len(images.Posters) == 0 {
		panic("no posters")
	}
	poster := images.Posters[0]
	for _, p := range images.Posters {
		if p.Language == "en" {
			poster = p
			break
		}
	}
	posterURL := "https://img.amodb.dev/t/p/w500" + poster.FilePath
	img, err := client.Get(posterURL)
	if err != nil {
		panic(err)
	}
	defer img.Body.Close()
	fmt.Println(img.StatusCode, img.Header.Get("Content-Type"), posterURL)
}
```

### Parametry

| Parametr                 | Kde   | Povinný       | Popis                                                                                                                                                                   |
| ------------------------ | ----- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `movie_id`               | path  | ano           | Číselné ID filmu, například `550`.                                                                                                                                      |
| `api_key`                | query | jeden ze dvou | Váš klíč. Použijte jej, nebo hlavičku `Authorization: Bearer`.                                                                                                          |
| `include_image_language` | query | ne            | Kódy ISO 639-1 oddělené čárkou. Přidejte `null`, aby se zahrnuly obrázky bez textu, například `en,null`. Vrátí se jen uvedené jazyky. Bez něj dostanete všechny jazyky. |
| `language`               | query | ne            | Na tomto endpointu se přijímá, ale ignoruje. Jazyky vybírejte přes `include_image_language`.                                                                            |

### Pole odpovědi

| Pole                            | Typ              | Poznámky                                                                                                               |
| ------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `id`                            | integer          | ID filmu.                                                                                                              |
| `backdrops`, `logos`, `posters` | array            | Jedno pole na druh obrázku, v tomto pořadí klíčů. Každé může být prázdné.                                              |
| `file_path`                     | string           | Začíná lomítkem. Připojte jej k velikosti na hostiteli obrázků. Plakáty a pozadí jsou `.jpg`, loga `.png` nebo `.svg`. |
| `width`, `height`               | integer          | Rozměr původního souboru v pixelech. `0`, když rozměr není znám.                                                       |
| `aspect_ratio`                  | number           | Šířka dělená výškou. Plakáty jsou kolem 0.667, pozadí kolem 1.778. `0`, když rozměr není znám.                         |
| `iso_639_1`                     | string nebo null | Jazyk textu na obrázku. `null` znamená bez textu.                                                                      |
| `vote_average`, `vote_count`    | number, integer  | U obrázků filmů a seriálů vždy `0`, takže jimi nelze obrázky řadit. Ponechte pořadí, které API vrací.                  |

### Příklad odpovědi

Zobrazeny jsou dvě položky v každém poli.

```json
{
  "id": 550,
  "backdrops": [
    {
      "aspect_ratio": 1.778,
      "height": 1440,
      "iso_639_1": null,
      "file_path": "/c6OLXfKAk5BKeR6broC8pYiCquX.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 2560
    },
    {
      "aspect_ratio": 1.778,
      "height": 1080,
      "iso_639_1": "en",
      "file_path": "/b9HyPoxwxjxkWEUL5ErZdhApQe2.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1920
    }
  ],
  "logos": [
    {
      "aspect_ratio": 4.638,
      "height": 389,
      "iso_639_1": "en",
      "file_path": "/7Uqhv24pGJs4Ns31NoOPWFJGWNG.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1804
    },
    {
      "aspect_ratio": 0.848,
      "height": 1295,
      "iso_639_1": "en",
      "file_path": "/4XkF0Rf7gvSfea8fYLFbU5tmuJw.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1098
    }
  ],
  "posters": [
    {
      "aspect_ratio": 0.667,
      "height": 3000,
      "iso_639_1": "en",
      "file_path": "/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 2000
    },
    {
      "aspect_ratio": 0,
      "height": 0,
      "iso_639_1": null,
      "file_path": "/qkrH7rjYKU4KOwwIl6wF6H3ISvm.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 0
    }
  ]
}
```

Druhý plakát ukazuje položku, jejíž rozměr není znám. Soubor se přesto načte.

## Sestavení URL obrázku

Spojte tři části: `https://img.amodb.dev/t/p/`, segment velikosti a `file_path`. Cesta už začíná lomítkem, takže `https://img.amodb.dev/t/p/w500` plus `/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg` je úplná URL.

Velikost je `w` plus šířka v pixelech, `h` plus výška v pixelech, nebo `original` pro uložený soubor. Hostitel obsluhuje deset velikostí: `w92`, `w154`, `w185`, `w300`, `w342`, `w500`, `w780`, `w1280`, `h632` a `original`. Jakákoli jiná velikost, například `w400`, odpoví 404. `/3/configuration` uvádí velikosti, které se hodí pro každý druh obrázku.

| Druh   | Pole konfigurace | Velikosti                                                 |
| ------ | ---------------- | --------------------------------------------------------- |
| Plakát | `poster_sizes`   | `w92`, `w154`, `w185`, `w342`, `w500`, `w780`, `original` |
| Pozadí | `backdrop_sizes` | `w300`, `w780`, `w1280`, `original`                       |
| Logo   | `logo_sizes`     | `w92`, `w154`, `w185`, `w300`, `w500`, `original`         |
| Profil | `profile_sizes`  | `w185`, `h632`, `original`                                |
| Záběr  | `still_sizes`    | `w92`, `w185`, `w300`, `original`                         |

Hostitel druh nekontroluje, takže se plakát načte i ve velikosti `w1280`. Držte se velikostí uvedených pro daný druh, aby váš kód odpovídal konfiguraci a jakémukoli klientovi TMDB.

Hostitel obrázků klíč nepotřebuje a edge uchovává každý soubor 30 dní. Protože se neposílá klíč, načítání obrázků nespotřebovává vaše požadavky za minutu. Odpovědi nesou `Access-Control-Allow-Origin: *`, takže je prohlížeč může načíst z libovolné stránky. Neznámá velikost nebo neznámý soubor odpoví 404 s tělem JSON.

## Responzivní obrázky se srcset

Vyberte nejmenší velikost, která stále pokryje zobrazenou šířku krát hustotu obrazovky. Plakát zobrazený o šířce 171 pixelů CSS potřebuje na obrazovce 2x `w342`. Tato pomocná funkce sestaví `srcset` z uložené cesty.

```js
const WIDTHS = [185, 342, 500, 780];

function posterSrcset(filePath) {
  return WIDTHS.map((w) => `https://img.amodb.dev/t/p/w${w}${filePath} ${w}w`).join(', ');
}

const path = '/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg';
console.log(`<img src="https://img.amodb.dev/t/p/w342${path}" srcset="${posterSrcset(path)}" sizes="(max-width: 600px) 50vw, 342px" alt="Fight Club poster">`);
```

## Další endpointy obrázků

Všechny cesty níže používají základ `https://api.amodb.dev/3` a vracejí pole uvedená ve druhém sloupci.

| Metoda a cesta                                                               | Vrácená pole                                                  | Parametry                |
| ---------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------ |
| `GET /tv/{series_id}/images`                                                 | `backdrops`, `logos`, `posters`                               | `include_image_language` |
| `GET /tv/{series_id}/season/{season_number}/images`                          | `posters`, vždy prázdné                                       | žádné                    |
| `GET /tv/{series_id}/season/{season_number}/episode/{episode_number}/images` | `stills`, jedna položka s `width` a `height` nastavenými na 0 | žádné                    |
| `GET /person/{person_id}/images`                                             | `profiles`                                                    | žádné                    |

U filmů a seriálů můžete také přidat `append_to_response=images` k volání detailů. `include_image_language` funguje i tam. Přidaný blok nemá vlastní `id`.

Profily osob jsou jediné místo, kde `vote_average` nese skutečné skóre. `id` v odpovědi sezóny nebo epizody je ID sezóny nebo epizody. Nadřazené záznamy viz [osoby](https://amodb.dev/cs/people/) a [seriály](https://amodb.dev/cs/tv-series/).

amodb nenabízí cesty images pro kolekce, společnosti a sítě. Jejich záznamy už obsahují jedno `poster_path`, `backdrop_path` nebo `logo_path`, popsané na stránkách [kolekce](https://amodb.dev/cs/collections/) a [společnosti a televizní sítě](https://amodb.dev/cs/companies-networks/).

## Endpoint konfigurace

`GET /3/configuration` vrací blok `images` s `secure_base_url` nastaveným na `https://img.amodb.dev/t/p/`, `base_url` (prostá forma http) a seznamy velikostí `backdrop_sizes`, `logo_sizes`, `poster_sizes`, `profile_sizes` a `still_sizes`. Přečtěte jej jednou při startu, použijte zabezpečenou formu a URL z něj sestavujte místo pevného zadání velikostí. Edge jej cachuje 24 hodin.

## Chyby

| HTTP | status_code | Kdy                                                                                                     |
| ---- | ----------- | ------------------------------------------------------------------------------------------------------- |
| 401  | 7           | Klíč chybí nebo je nesprávný při volání JSON.                                                           |
| 402  | 36          | Platnost tarifu skončila.                                                                               |
| 404  | 34          | Osoba, sezóna nebo epizoda s tímto ID neexistuje, nebo neznámá velikost či soubor na hostiteli obrázků. |
| 405  | 37          | Použili jste metodu pro zápis na cestě images.                                                          |
| 429  | 25          | Překročili jste počet požadavků za minutu. Počkejte tolik sekund, kolik říká `Retry-After`.             |

ID filmu nebo seriálu, které neexistuje, zde není chyba: cesta images odpoví 200 s prázdnými poli, zatímco cesta detailů odpoví 404. Úplný seznam viz [chyby](https://amodb.dev/cs/errors/). Požadavky na soubory obrázků jsou prosté načtení HTTP, kontrolujte proto stavový kód odpovědi místo parsování těla JSON.

## Praktické poznámky

- Ukládejte `file_path` do databáze a URL sestavujte při vykreslování. Nová velikost nebo hostitel pak stojí jednu změnu kódu.
- Předejte `include_image_language` s jazykem zobrazení plus `null`, například `ru,null`, aby se neobjevovaly plakáty s cizím textem.
- Prázdné pole je běžné 200. Použijte záložní `poster_path` ze záznamu [detailu filmu](https://amodb.dev/cs/movies/).
- Pro hero pozadí přes celou šířku použijte `w1280` a pro karty `w780`. `original` je uložený soubor v plném rozlišení a je mnohem větší než `w780`.
- Kopie na edge žijí 30 dní a jsou sdílené, takže soubor, který vyžádal jeden klient, se dalšímu obslouží z cache.

## Otázky a odpovědi

### Vyžadují požadavky na obrázky API klíč?

Ne. Soubory na img.amodb.dev/t/p/{size}/{file} jsou veřejné, takže je můžete používat přímo ve značkách img a v CSS. Klíč potřebují jen endpointy JSON, které vypisují cesty k souborům.

### Které velikosti obrázků mohu vyžádat?

w92, w154, w185, w300, w342, w500, w780, w1280, h632 a original. Jakákoli jiná velikost odpoví 404. /3/configuration uvádí, které z nich se hodí pro každý typ obrázku, a tabulka velikostí na této stránce to opakuje.

### Jak získám plakáty jen v jednom jazyce?

Předejte include_image_language se seznamem odděleným čárkami, například en,null. Hodnota null přidá obrázky bez textu. Vrátí se jen uvedené jazyky. Parametr language obrázky nefiltruje.

### Proč cesta k souboru začíná lomítkem?

Cesty ve stylu TMDB zahrnují úvodní lomítko, takže je lze připojit přímo ke segmentu velikosti. Ukládejte samotnou cestu a úplnou URL sestavte při vykreslování.

## Související stránky

- [API detailu filmu](https://amodb.dev/cs/movies/): API detailu filmu se stejnými cestami a JSON jako TMDB v3. Načtěte film podle ID, přidejte obsazení, hodnocení a nálady přes append_to_response, 14 jazyků.
- [API detailu seriálu](https://amodb.dev/cs/tv-series/): API detailu seriálu se stejnými cestami a JSON jako TMDB v3. Seriál podle ID se sezónami, sítěmi, věkovým hodnocením a poskytovateli streamování.
- [API detailu osoby](https://amodb.dev/cs/people/): API detailu osoby se stejnými cestami a JSON jako TMDB v3. Herec či člen štábu podle ID s biografií, filmografií, externími ID a seznamem populárních osob.
- [API kolekcí](https://amodb.dev/cs/collections/): API kolekcí filmů s cestami TMDB v3: načtěte franšízu podle ID se všemi filmy, čtěte belongs_to_collection u filmu a hledejte kolekce podle názvu.
- [API plakátů filmů a CDN obrázků](https://amodb.dev/cs/movie-poster-api/): API plakátů filmů s hostitelem obrázků bez klíče. Velikosti od w92 po original, seznamy srcset a výběr plakátů podle jazyka přes include_image_language.
- [Rychlý start](https://amodb.dev/cs/quickstart/): První volání amodb: získejte klíč, vyžádejte detail filmu v curl, JavaScriptu, Pythonu, PHP nebo Go a načtěte plakát z img.amodb.dev. Za méně než 2 minuty.

Aktualizováno: 2026-10-18. Source: https://amodb.dev/cs/images-api/
