图片

在 Astro 项目中,有很多种在网站中使用图片的方式。无论是用存储在项目中的图片,还是链接外部图片,亦或从像 CMS(内容管理系统)或 CDN(内容分发网络)这样的地方加载图片,都没问题!

你可以在 .astro 文件中使用标准的 HTML <img><img /> 元素来展示图片,同时也支持所有 HTML 图片属性。

src/pages/index.astro
---
import rocket from '../images/rocket.svg';
---
<!-- 位于其它服务器上的图片 -->
<img src="https://astro.build/assets/logo.png" width="25" alt="Astro 的 logo">

<!-- 存储在 public/assets/stars.png 的本地图片 -->
<img src="/assets/stars.png" alt="一片繁星闪烁的夜空。">

<!-- 存储在 src/images/rocket.svg 的本地图片 -->
<img src={rocket} alt="外空中的一架火箭。"/>

可以在 .md 文件中使用 Markdown 标准语法 ![](),或 HTML 标准语法 <img> 标签,来调用位于 public/ 文件夹下或其它服务器上的图片。

src/pages/post-1.md
# 试着写个 Markdown 吧!

<!-- 存储在 public/assets/stars.png 的本地图片 -->
![一片繁星闪烁的夜空。](/assets/stars.png)
<img src="/assets/stars.png" alt="一片繁星闪烁的夜空。">

<!-- 位于其它服务器上的图片 -->
![Astro 的 logo](https://astro.build/assets/logo.png)
<img src="https://astro.build/assets/logo.png" width="25" alt="Astro 的 logo">

在你的 .mdx 文件中使用标准 Markdown 语法的 ![]() 或 JSX 的 <img /> 标签,来包含你的 public/ 目录下或其它服务器上的图片,就和在 Markdown 文件里一样。不过,MDX 文件还允许你以 Astro 组件的形式导入你的 src 文件夹内的图片并使用。

src/pages/post-1.md
import rocket from '../images/rocket.svg';

# My MDX Page

// 存放在项目中 src/images/rocket.svg 路径的图片
<img src={rocket} alt="外空中的一架火箭。"/>

// 存放在项目中 public/assets/stars.png 路径的图片
![一片繁星闪烁的夜空。](/assets/stars.png)
<img src="/assets/stars.png" alt="一片繁星闪烁的夜空。" />

// 位于其它服务器上的图片
![Astro 的图标](https://astro.build/assets/logo.png)
<img src="https://astro.build/assets/logo.png" width="25" alt="Astro 的 logo" />

需要与之对应的语法将图片转化为 UI 框架中的组件 (例如在 React 或 Svelte 中)。

src/ 下存放的图片需要先以相对路径别名导入,然后通过图片的 src 属性来引用。

src/pages/index.astro
---
// Access images in `src/images/`
import logo from '../images/logo.png';
---
<img src={logo} width="40" alt="Astro 的图标" />

Astro 项目树中的 public/ 目录 为无需在 Astro 构建过程中处理的文件与资源设置,存放于其中的图片将会被原样拷贝到构建出的文件夹中。请注意,这些图片不以导入到你的 .astro 文件中的方式使用(即,应直接以相对路径方式使用),且它们的 src 属性应填写为基于 public/ 目录的相对路径

src/pages/index.astro
---
// 存取放在 `public/images/` 里的图片
---
<img src="/images/logo.png" />

Astro 官方的「图片」集成提供了两种用以渲染经过优化的图片的 Astro 组件: <Image /><Picture />

安装这一 Astro 集成 (EN)之后,你便可以导入这两个组件,并在任何你想用的地方用上它们,包括用在 .mdx 文件里!

Astro 的 <Image /> 组件 (EN) 可以帮你优化图片,并指定宽度、长度和/或长宽比。它甚至能协助你将图片转为某一特定格式,使你无需专门处理不同类型的图片。

当你需要保持不同终端上图片显示大小的一致,或者精细地控制图片质量(例如 logo)时,这个组件会很有用。

存放在项目的源文件夹中的图片可以在主页中导入并用在 <Image /> 组件的 src 属性。其它属性的是否填写是可选的,若是未提供,则默认为图片本身的属性。

使用远程图片时,<Image />src 属性需要一个完整的链接。除此之外,你还需要:同时提供 widthheight 属性,或同时提供以上二者之一和 aspectRatio 属性。

src/pages/index.astro
---
import { Image } from '@astrojs/image/components';
import localImage from '../assets/local.png';
const imageUrl = 'https://astro.build/assets/logo.png';
---

// 经过优化的本地图片,但保留了原始的宽度、长度与格式
<Image src={localImage} />

// 此时图片的高度将基于原始图片的长宽比或自行指定的长宽比计算。
// 请注意,仅当加载本地图片时,”基于原始图片的长宽比“计算方法才适用。
<Image src={localImage} width={300} />
<Image src={imageUrl} width={300} aspectRatio={16/9} />

// 此时图片将被缩放到指定的宽度与高度
<Image src={localImage} width={300} height={600} />
<Image src={imageUrl} width={544} height={184} />

// 此时图片将被缩放到指定的长宽比并转换为 avif 格式
<Image src={localImage} aspectRatio="16:9" format="avif" />
<Image src={imageUrl} height={200} aspectRatio="16:9" format="avif" />

// 若为本地图片则可以在行内导入
<Image src={import('../assets/local.png')} />

Astro 的 <Picture /> 组件 (EN)能够给你的网站提供响应式的图片,这意味着图片可以有多种尺寸、格式和排版。你可以允许用户的浏览器基于屏幕尺寸与带宽等因素自行选择合适的尺寸、分辨率与格式,也可以定下基于 media queries 的规则约束它们。

这个组件能用于呈现形式的设计,优化用户在不同尺寸屏幕上观看的体验。

除图片原始格式外,<Picture /> 组件还会生成 avifwebp 两种格式的图片。

可以在 frontmatter 中导入存储在 src 文件夹中的本地图片,并将其用于 <Picture /> 组件。但 <Picture /> 组件的 srcwidthssizes 属性不能为空。

除了 srcwidthssizes,位于远端的图片还需要设定 aspectRatio 属性,从而让 height,即高度,在编译期就能计算出来。

---
import { Picture } from '@astrojs/image/components';
import localImage from '../assets/localImage.png';
const imageUrl = 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png';
---

// 有着多种尺寸与格式的本地图片
<Picture src={localImage} widths={[200, 400, 800]} sizes="(max-width: 800px) 100vw, 800px" formats={['avif', 'jpeg', 'png', 'webp']} alt="这是一张本地图片" />

// 对位于远端的图片而言,长宽比也是必填项
<Picture src={imageUrl} widths={[200, 400, 800]} aspectRatio="4:3" sizes="(max-width: 800px) 100vw, 800px" alt="这是一张远端图片" />

// `<Picture />` 组件也支持 inline 导入语法
<Picture src={import("../assets/localImage.png")} widths={[200, 400, 800]} sizes="(max-width: 800px) 100vw, 800px" alt="这是一张本地图片" />

.mdx 文件中,可以将 importexport 获取的图片 src 传入<Image /><Picture /> 组件。

src/pages/index.mdx
import { Image, Picture } from '@astrojs/image/components';
import rocket from '../assets/rocket.png';
export const galaxy = 'https://astro.build/assets/galaxy.jpg';

<Image src={import('../assets/logo.png')} alt="Astro 的 logo"/>
<Image src={rocket} width={300} alt="漂上月球,宇宙飞船。">
<Picture src={rocket} widths=[{200, 400, 800}] sizes="(max-width: 800px) 100vw, 800px" alt="火箭发射中……" />
<Picture src={galaxy} widths=[{200, 400, 800}] aspectRatio={16/9} sizes="(max-width: 800px) 100vw, 800px" alt="外空。" />

Astro 与图片 CDN 可以无缝集成。就像写 HTML 或者 JSX 一样,只需将图片链接用作 <img>src 属性即可。若使用 <Image /> 组件与 <Picture /> 组件,则是将原创链接填入 src 属性。

或是你的 CDN 提供了 Node.js SDK,那么你便可以将之用于项目中。例如,Cloudinary 的 SDK 会自动为你生成带有合适的 src 属性的 <img> 标签。

除了官方的 @astrojs/image (EN) 集成外,社区还开发了一些用于图片的集成,它们能够帮你处理并优化 Astro 项目中的图片。