https://picsum.photos/(官方称为 Lorem Picsum)是一个非常实用的免费 API,它提供高质量的随机占位图片。对于开发者来说,它极其方便,无论是快速搭建 UI 原型、填充测试数据,还是作为小型应用中的随机图片来源,都非常适合。
下面我们来详细说说它的用法和在 JSBox 中的集成。
Lorem Picsum (https://picsum.photos/) 详细用法
Lorem Picsum 的设计哲学是极简主义,它的用法非常直观。
一、基本用法:获取随机图片
最简单的用法是直接指定图片的宽度和高度。
-
API:
https://picsum.photos/{width}/{height} -
示例:
-
https://picsum.photos/200/300- 返回一张宽度 200 像素,高度 300 像素的随机图片。 -
https://picsum.photos/400- 返回一张宽度和高度都是 400 像素的正方形随机图片(如果只提供一个维度,则假定为正方形)。
-
每次刷新这个 URL,你都会得到一张不同的随机图片。
二、获取指定图片:通过 ID
如果你想获取某张特定的图片,并且每次都一样,你可以使用图片的 ID。图片的 ID 可以通过 List API 获取(后面会讲)。
-
API:
https://picsum.photos/id/{id}/{width}/{height} -
示例:
https://picsum.photos/id/237/200/300- 返回 ID 为 237 的图片,尺寸 200x300。
三、保持随机但可重复:通过 Seed
如果你想要每次获取的图片是随机的,但对于同一个“种子”,每次请求都能得到相同的随机图片,可以使用 seed。这在测试或需要可预测的随机性时非常有用。
-
API:
https://picsum.photos/seed/{seed}/{width}/{height} -
示例:
https://picsum.photos/seed/myuniqueid/200/300- 每次请求这个 URL,即使是随机的,也会得到同一张图片。
四、图片修饰:灰度与模糊
Lorem Picsum 还提供了简单的图片修饰功能。
-
灰度 (Grayscale)
-
API: 在 URL 后添加
?grayscale -
示例:
https://picsum.photos/200/300?grayscale- 返回一张 200x300 的灰度随机图片。
-
-
模糊 (Blur)
-
API: 在 URL 后添加
?blur或?blur={amount}(模糊量从 1 到 10) -
示例:
-
https://picsum.photos/200/300?blur- 默认模糊量。 -
https://picsum.photos/200/300?blur=5- 返回一张中等模糊的图片。
-
-
-
同时使用: 可以组合使用
&符号。- 示例:
https://picsum.photos/200/300?grayscale&blur=2- 返回一张灰度且轻微模糊的图片。
- 示例:
五、获取图片列表和元数据
除了直接获取图片,你还可以获取一个图片列表,包含每张图片的 ID、作者、URL 等信息。
-
获取图片列表:
-
API:
https://picsum.photos/v2/list -
分页:
https://picsum.photos/v2/list?page={page}&limit={limit}-
page: 页码 (从 1 开始)。 -
limit: 每页返回的图片数量 (最大通常为 100)。
-
-
响应示例 (JSON 数组):
[ { "id": "0", "author": "Alejandro Escamilla", "width": 5000, "height": 3333, "url": "https://unsplash.com/photos/yC-YJtJrxP4", "download_url": "https://picsum.photos/id/0/5000/3333" }, { "id": "1", "author": "Alejandro Escamilla", "width": 5000, "height": 3333, "url": "https://unsplash.com/photos/LNRyGwQM7Ts", "download_url": "https://picsum.photos/id/1/5000/3333" } // ... ]download_url字段是直接可用于获取图片的 URL。
-
-
获取单张图片元数据:
-
API:
https://picsum.photos/id/{id}/info -
示例:
https://picsum.photos/id/237/info- 返回 ID 237 图片的详细信息。
-
在 JSBox 中使用 Lorem Picsum
Lorem Picsum 非常适合在 JSBox 中进行网络请求和图片显示练习。
1. 在 image 控件中直接显示随机图片
这是最简单快捷的方式。
$ui.render({
props: {
title: "随机图片",
bgcolor: $color("systemBackground"),
theme: "auto"
},
views: [
{
type: "image",
props: {
// 直接使用 URL 作为 src
src: "https://picsum.photos/400/600", // 每次运行都会显示不同的图片
contentMode: $contentMode.scaleAspectFit // 保持图片宽高比并适应视图
},
layout: (make) => {
make.center.equalTo(make.super);
make.width.equalTo(300);
make.height.equalTo(450);
}
},
{
type: "button",
props: { title: "换一张" },
layout: (make) => {
make.centerX.equalTo(make.super);
make.top.equalTo($("image").bottom).offset(20);
make.size.equalTo($size(100, 40));
},
events: {
tapped: (sender) => {
// 动态更新图片 src
$("image").src = `https://picsum.photos/400/600?${Date.now()}`; // 加一个时间戳确保强制刷新
$ui.toast("已换新图片");
}
}
}
]
});
2. 下载图片数据并进行操作(例如保存、分享或处理)
如果你需要对图片进行额外的操作(如保存到文件、分享、进行图像处理),你需要先下载它的原始数据。
$ui.render({
props: {
title: "下载与操作图片",
bgcolor: $color("systemBackground"),
theme: "auto"
},
views: [
{
type: "button",
props: { title: "下载并分享" },
layout: $layout.center,
events: {
tapped: async (sender) => {
$ui.loading(true);
$ui.toast("下载中...");
try {
// 下载一张灰度模糊图片
const imageUrl = "https://picsum.photos/600/800?grayscale&blur=3";
const resp = await $http.download({ url: imageUrl });
$ui.loading(false);
if (resp.error) {
$ui.alert("下载失败: " + resp.error.localizedDescription);
return;
}
if (resp.data) {
$share.sheet(resp.data); // 分享图片数据
$ui.toast("图片下载完成,已调起分享。");
// 也可以选择保存到文件
// const saveSuccess = $file.write({ data: resp.data, path: "downloaded_image.jpg" });
// if (saveSuccess) $ui.toast("图片已保存到文件。");
// else $ui.alert("图片保存失败。");
} else {
$ui.alert("未获取到图片数据。");
}
} catch (e) {
$ui.loading(false);
$ui.alert("操作异常: " + e.message);
console.error("图片下载或操作错误:", e);
}
}
}
}
]
});
3. 获取图片列表并显示在 matrix(网格)中
这是一个更复杂的例子,结合了网络请求、JSON 解析和 matrix 控件的用法。
$ui.render({
props: {
title: "图片画廊",
bgcolor: $color("systemBackground"),
theme: "auto"
},
views: [
{
type: "matrix",
props: {
id: "imageMatrix", // 给 matrix 控件一个 ID
columns: 3, // 每行 3 列
itemHeight: 120, // 每个图片项的高度
spacing: 5, // 项间距
template: {
// 定义每个图片项的视图模板
views: [
{
type: "image",
props: {
id: "itemImage", // 模板中图片的 ID
contentMode: $contentMode.scaleAspectFill, // 图片填充并裁剪
clipsToBounds: true, // 裁剪超出部分
cornerRadius: 8
},
layout: $layout.fill // 图片填充整个项
},
{
type: "label",
props: {
id: "itemAuthor", // 模板中作者标签的 ID
font: $font(10),
textColor: $color("white"),
align: $align.center,
bgcolor: $rgba(0, 0, 0, 0.4) // 半透明背景
},
layout: (make) => {
make.left.right.bottom.equalTo(0); // 位于项底部
make.height.equalTo(20);
}
}
]
},
data: [], // 初始空数据
actions: [ // 左滑动作
{
title: "作者",
color: $color("systemBlue"),
handler: (sender, indexPath, data) => {
$ui.alert(`作者: ${data.itemAuthor.text}`);
}
},
{
title: "下载",
color: $color("systemGreen"),
handler: async (sender, indexPath, data) => {
$ui.loading(true);
try {
const resp = await $http.download({ url: data.itemImage.src });
$ui.loading(false);
if (resp.error) throw new Error(resp.error.localizedDescription);
if (resp.data) {
$share.sheet(resp.data);
$ui.toast("图片下载并分享完成!");
}
} catch (e) {
$ui.alert("下载失败: " + e.message);
}
}
}
]
},
layout: $layout.fill,
events: {
didSelect: (sender, indexPath, data) => {
// 点击图片时预览大图
$ui.preview({
title: data.itemAuthor.text,
url: data.itemImage.src // 使用原始 URL 进行预览
});
},
pulled: async (sender) => { // 下拉刷新加载新页
await loadImages(sender);
sender.endRefreshing();
},
didReachBottom: async (sender) => { // 滚动到底部加载下一页
await loadImages(sender, true);
sender.endFetchingMore();
}
}
}
]
});
let currentPage = 1; // 当前页码
const imagesPerPage = 30; // 每页图片数量
/**
* 加载图片到 Matrix 列表
* @param {Object} [sender] - 事件发送者 (用于下拉刷新/加载更多)
* @param {boolean} [append=false] - 是否追加数据
*/
async function loadImages(sender, append = false) {
if (!append) { // 如果不是追加,则重置页码
currentPage = 1;
}
$ui.loading(true);
try {
const listUrl = `https://picsum.photos/v2/list?page=${currentPage}&limit=${imagesPerPage}`;
const resp = await $http.get({ url: listUrl });
$ui.loading(false);
if (resp.error) {
$ui.alert("加载图片列表失败: " + resp.error.localizedDescription);
return;
}
const rawImages = resp.data;
if (!rawImages || rawImages.length === 0) {
$ui.toast("没有更多图片了。");
return;
}
const matrixData = rawImages.map(img => ({
itemImage: { src: img.download_url }, // 将 download_url 作为图片 src
itemAuthor: { text: img.author } // 将作者作为标签文本
}));
const currentMatrix = $("imageMatrix");
if (append) {
// 获取当前数据并追加
const existingData = currentMatrix.data.length > 0 ? currentMatrix.data[0].rows : [];
currentMatrix.data = [{ rows: existingData.concat(matrixData) }];
} else {
currentMatrix.data = [{ rows: matrixData }];
}
currentPage++; // 增加页码,为下次加载做准备
} catch (e) {
$ui.loading(false);
$ui.alert("加载图片异常: " + e.message);
console.error("加载图片列表错误:", e);
}
}
// 首次加载图片
loadImages();
最佳实践与提示:
-
URL 强制刷新:
https://picsum.photos/200/300这样的 URL 可能会被浏览器缓存。如果你想要每次点击按钮都获取一张全新的随机图片,可以在 URL 后添加一个不影响请求结果的随机参数,例如https://picsum.photos/200/300?${Date.now()}。 -
缓存: 对于已经下载的图片,如果你需要重复使用,可以考虑使用
$cache或$file进行本地缓存,减少网络请求。 -
错误处理: 始终对网络请求结果进行
resp.error检查,并使用try...catch捕获 Promise 链中的错误。 -
图片模式:
contentMode: $contentMode.scaleAspectFill和clipsToBounds: true组合常用于网格布局,使图片填充整个区域并裁剪多余部分,达到美观的视觉效果。 -
作者归属: 在公共项目或需要遵循版权协议的场景中,请确保为图片作者进行适当的归属。
通过这些示例,你可以充分利用 Lorem Picsum API 在 JSBox 中实现各种有趣的图片功能!