兰 亭 墨 苑
期货 · 量化 · AI · 终身学习
首页
归档
编辑文章
标题 *
URL 别名 *
内容 *
(支持 Markdown 格式)
`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 还提供了简单的图片修饰功能。 1. **灰度 (Grayscale)** * **API**: 在 URL 后添加 `?grayscale` * **示例**: `https://picsum.photos/200/300?grayscale` - 返回一张 200x300 的灰度随机图片。 2. **模糊 (Blur)** * **API**: 在 URL 后添加 `?blur` 或 `?blur={amount}` (模糊量从 1 到 10) * **示例**: * `https://picsum.photos/200/300?blur` - 默认模糊量。 * `https://picsum.photos/200/300?blur=5` - 返回一张中等模糊的图片。 3. **同时使用**: 可以组合使用 `&` 符号。 * **示例**: `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 数组)**: ```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` 控件中直接显示随机图片 这是最简单快捷的方式。 ```javascript $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. 下载图片数据并进行操作(例如保存、分享或处理) 如果你需要对图片进行额外的操作(如保存到文件、分享、进行图像处理),你需要先下载它的原始数据。 ```javascript $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` 控件的用法。 ```javascript $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 中实现各种有趣的图片功能!
配图 (可多选)
选择新图片文件或拖拽到此处
标签
更新文章
删除文章