# 电影海报 API 与图片 CDN

> 海报从 img.amodb.dev 加载，无需 API 密钥，路径为 /t/p/{size}/{file}，file 取自响应中的 poster_path。尺寸名从 w92 到 original，可按语言选图。仅 JSON 调用需要密钥。

## 无需密钥的电影海报图片主机

海报 URL 是 `https://img.amodb.dev/t/p/{size}/{file}`。file 部分是任意电影、搜索或列表响应中的 `poster_path` 字符串，以斜杠开头。size 部分是 `w342` 这样的名称。图片无需密钥，因此浏览器和应用可以直接加载。告诉你文件名的 JSON 仍然需要你的密钥。amodb 是使用 TMDB v3 协议的独立 API，所以更换主机后，现有的图片代码仍可继续使用。

你会得到：

- 同一个主机上的海报、背景图、标志、人物照片和剧集剧照。
- 十种尺寸名，从 `w92` 到 `original`。
- 每部作品的海报列表，每项带有语言、宽度和高度。
- 图片在边缘缓存 30 天。

## 可获取的数据

| 图片        | 文件名来自                                     | 常用尺寸                                                |
| --------- | ----------------------------------------- | --------------------------------------------------- |
| 电影海报      | `/3/movie/{movie_id}` 和列表中的 `poster_path` | `w92`、`w154`、`w185`、`w342`、`w500`、`w780`、`original` |
| 背景图       | `backdrop_path`                           | `w300`、`w780`、`w1280`、`original`                    |
| 人物照片      | `/3/person/{person_id}` 上的 `profile_path` | `w185`、`h632`、`original`                            |
| 公司或电视网标志  | `logo_path`                               | `w92`、`w154`、`w185`、`w300`、`w500`、`original`        |
| 剧集剧照      | `still_path`                              | `w92`、`w185`、`w300`、`original`                      |
| 一部作品的所有海报 | `GET /3/movie/{movie_id}/images`          | `posters` 数组                                        |

电视剧、季和系列合集也带有 `poster_path`。请在启动时从 `GET /3/configuration` 的 `images` 块读取一次确切的尺寸列表，而不是写死。图片参考见[图片](https://amodb.dev/zh/images-api/)。

## 三步开始

1. 在[定价](https://amodb.dev/zh/pricing/)页选择套餐。它决定 JSON 调用的速率：每分钟 20、40 或 120 个请求。
2. 在账户后台创建密钥。
3. 从详情或列表调用中读取 `poster_path`，再把它接到图片主机和尺寸名之后。

## 请求示例

这个 Go 程序列出《黑客帝国》（电影 ID 603）的英文海报和不含文字的海报，选出最宽的一张，打印现成的 `srcset`，并保存 `w342` 文件。密钥只用于 JSON 调用。

```bash
# the JSON call needs the key
curl -s "https://api.amodb.dev/3/movie/603/images?include_image_language=en,null" \
  -H "Authorization: Bearer $AMODB_KEY"

# the image call does not
curl -s -o poster.jpg "https://img.amodb.dev/t/p/w342/aOIuZAjPaRIE6CMzbazvcHuHXDc.jpg"
```

```go
package main

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

const imgBase = "https://img.amodb.dev/t/p/"

type poster struct {
	FilePath string  `json:"file_path"`
	Lang     *string `json:"iso_639_1"`
	Width    int     `json:"width"`
}

type images struct {
	Posters []poster `json:"posters"`
}

func srcset(file string) string {
	var parts []string
	for _, w := range []int{185, 342, 500, 780} {
		parts = append(parts, fmt.Sprintf("%sw%d%s %dw", imgBase, w, file, w))
	}
	return strings.Join(parts, ", ")
}

func main() {
	client := &http.Client{Timeout: 10 * time.Second}

	url := "https://api.amodb.dev/3/movie/603/images?include_image_language=en,null"
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		panic(res.Status)
	}

	var imgs images
	if err := json.NewDecoder(res.Body).Decode(&imgs); err != nil {
		panic(err)
	}
	if len(imgs.Posters) == 0 {
		fmt.Println("no posters")
		return
	}

	best := imgs.Posters[0]
	for _, p := range imgs.Posters {
		if p.Width > best.Width {
			best = p
		}
	}
	lang := "none"
	if best.Lang != nil {
		lang = *best.Lang
	}
	fmt.Println("best poster:", best.FilePath, "language:", lang, "width:", best.Width)
	fmt.Println("srcset:", srcset(best.FilePath))

	// Image requests carry no key.
	pic, err := client.Get(imgBase + "w342" + best.FilePath)
	if err != nil {
		panic(err)
	}
	defer pic.Body.Close()
	if pic.StatusCode != http.StatusOK {
		panic(pic.Status)
	}
	out, err := os.Create("poster.jpg")
	if err != nil {
		panic(err)
	}
	defer out.Close()
	io.Copy(out, pic.Body)
}
```

`include_image_language=en,null` 的精简 images 响应：145 张海报中的 3 张，分别是一张英文海报、最宽的英文海报和一张不含文字的海报。响应还包含 `backdrops` 和 `logos`，此处省略。

```json
{
  "id": 603,
  "posters": [
    {
      "aspect_ratio": 0.667,
      "height": 2250,
      "iso_639_1": "en",
      "file_path": "/dXNAPwY7VrqMAo51EKhhCJfaGb5.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1500
    },
    {
      "aspect_ratio": 0.667,
      "height": 3000,
      "iso_639_1": "en",
      "file_path": "/aOIuZAjPaRIE6CMzbazvcHuHXDc.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 2000
    },
    {
      "aspect_ratio": 0.701,
      "height": 1426,
      "iso_639_1": null,
      "file_path": "/iLWzJxatuwwMT76dtMuwh3FEp2X.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1000
    }
  ]
}
```

## 选择尺寸

`w` 尺寸中的数字是图像宽度（像素），`h632` 表示高度。小尺寸节省带宽，大尺寸能在高密度屏幕上保留细节。

| 尺寸            | 典型用途          |
| ------------- | ------------- |
| `w92`         | 搜索建议和很小的列表行   |
| `w154`、`w185` | 密集的列表和卡片      |
| `w342`        | 手机上的网格卡片      |
| `w500`        | 详情页           |
| `w780`        | 大屏幕和 2x 显示屏   |
| `original`    | 存档或打印，未缩放的原文件 |

提供多个宽度，让浏览器自己选择。上面的 Go 程序会打印一个带有 `185w`、`342w`、`500w` 和 `780w` 候选项的 `srcset`。请搭配与你的布局相符的 `sizes` 属性，例如 `img` 元素上的 `sizes="(max-width: 600px) 45vw, 185px"`。

## 海报语言

`posters` 中的每一项都有 `iso_639_1` 值，要么是语言代码，要么是 null（表示不含文字的图稿）。`include_image_language` 参数接受用逗号分隔的代码列表。

| 取值        | 返回           |
| --------- | ------------ |
| `en`      | 标记为英语的海报     |
| `en,null` | 英语海报和不含文字的海报 |
| `null`    | 仅限不含文字的海报    |

较好的回退顺序是：用户语言的海报，然后是不含文字的海报，最后是英语海报。在每一组内部按 `width` 排序，并列时保留第一张。电影和电视剧图片上的 `vote_average` 和 `vote_count` 均为 `0`，所以它们无法用于排名。海报语言描述的是印在图稿上的文字，因此与 14 种界面语言无关。请检查返回内容的 `iso_639_1`，因为可用集合取决于作品。

## 保存和缓存海报

- 保存 `poster_path`，而不是完整 URL。之后可以据此拼出任意尺寸。
- 边缘节点缓存图片 30 天。详情缓存 6 小时，所以在此之后请重新读取 `poster_path`，看看是否有变化。
- 把密钥留在你的服务器上。只把图片 URL 发给浏览器。
- 当 `poster_path` 为 null 时，请渲染占位图，而不是裂开的图片。

## 对比

| 能力     | 抓取页面获取图片     | 自己托管副本      | amodb 图片主机                           |
| ------ | ------------ | ----------- | ------------------------------------ |
| 是否需要密钥 | 无，适用各网站的条款   | 无           | 图片无需密钥                               |
| 尺寸变体   | 页面提供什么尺寸就是什么 | 你自己生成并存储每一个 | URL 中的固定尺寸名，从 `w92` 到 `original`     |
| 查找文件   | 解析 HTML      | 你自己的数据库     | 每个响应中的 `poster_path`                 |
| 图稿语言   | 逐页处理         | 取决于你收集了什么   | images 接口上的 `include_image_language` |
| 存储与带宽  | 你的，外加来源网站的   | 你的          | 浏览器从 `img.amodb.dev` 加载              |
| 缓存     | 你的           | 你的          | 边缘缓存 30 天                            |

## 定价

图片下载不带密钥。套餐只限制为你提供文件名的 JSON 调用，而列表响应已经为每一项包含了 `poster_path`，所以一次列表调用就能填满整个网格。请在[定价](https://amodb.dev/zh/pricing/)页选择每分钟 20、40 或 120 个请求。访问需预付 1、3、6、12 或 24 个月，分别享受 0、10、20、30 和 40% 的折扣，不会自动续费，也没有免费额度。

## 常见问题

### 下载海报需要 API 密钥吗？

不需要。图片来自 https://img.amodb.dev/t/p/{size}/{file}，无需密钥，浏览器可以直接加载。只有返回 poster_path 的 JSON 调用才使用你的密钥。

### 有哪些海报尺寸？

尺寸名有 w92、w154、w185、w300、w342、w500、w780、w1280、h632 和 original。适合某种图片类型的尺寸，列在 GET /3/configuration 的 images 块中。

### 如何获取指定语言的海报？

调用 /3/movie/{id}/images?include_image_language=en,null，并读取每张海报的 iso_639_1。值为 null 表示不含文字的图稿。然后按宽度挑选。电影和剧集图片上的 vote_average 和 vote_count 均为 0。

### 图片缓存多久？

边缘节点会缓存图片 30 天。请保存 poster_path 的值而不是完整 URL，这样以后无需再次查询就能拼出任意其他尺寸。

### poster_path 为 null 时显示什么？

有些作品没有海报。请显示你自己设计的占位图，也可以在放弃之前调用 images 接口查找其他海报。

## 相关页面

- [图片 API 与图片主机](https://amodb.dev/zh/images-api/): 采用 TMDB v3 路径的电影图片 API：列出作品的海报、背景图、标志和剧照，再从 img.amodb.dev 以 10 种尺寸无密钥加载。
- [电影详情 API](https://amodb.dev/zh/movies/): 路径和 JSON 与 TMDB v3 相同的电影详情 API：按 ID 取电影，用 append_to_response 加入演职员和评分，支持 14 种语言。
- [电视剧 API](https://amodb.dev/zh/tv-series/): 路径和 JSON 与 TMDB v3 相同的电视剧 API。按 ID 获取剧集的季、电视网和下一集，以及内容分级和观看平台。
- [搜索 API](https://amodb.dev/zh/search/): 路径和 JSON 与 TMDB v3 相同的搜索 API。按文本查找电影、电视剧、人物、系列合集、公司和关键词，支持年份筛选和分页。
- [快速开始](https://amodb.dev/zh/quickstart/): 发出第一次 amodb 调用：获取密钥，用 curl、JavaScript、Python、PHP 或 Go 请求电影详情，再加载海报。
- [认证](https://amodb.dev/zh/authentication/): 如何发送 amodb 密钥：查询中的 api_key、Bearer 请求头，或 OMDb 的 apikey。含密钥格式、保管和 401 错误。

更新于: 2026-10-18. Source: https://amodb.dev/zh/movie-poster-api/
