之前一直是用第三方图片 API 当作博客文章封面,但是有一些图片并不符合我的审美。
API 的图片挺大的,用来当作壁纸合适,但是用来当小小的文章封面未免大材小用。一页博客,加载一张 API 的图片还好,加载多张就算是懒加载也有点力不从心了。
尝试过给 API 后面加上参数,限制长宽,似乎无效。
那还不如自己搞一个图片 API,里面放上我喜欢的图片。于是就有了下面的折腾。还有就是用上了 picgo cli,好像还有个压缩插件,就研究了下。
用到了 FFmpeg
,Cloudflare worker
,picgo compress
插件,还有几个图片在线处理网站。
图片获取
用了几张原来的 API 的图片,其他的是 B 站一个 up 的视频封面。用了获取B站(bilibili)视频封面图 – 下载 🦊 Firefox 扩展(zh-CN) 这个拓展获取。油猴脚本都过期无效了,功能也正常。
图片处理
抠图
在线抠图软件\_图片去除背景 | remove.bg – remove.bg,用了这个网站抠图,效果还不错。
在线处理
Photopea | Online Photo Editor,本来想左侧左下角任务占比百分之五十的,想了想没必要,不过这个网站还是比较直观的。
切割指定大小,转化 webp 格式
用到了 FFmpeg
,这个真是个强大的软件。用 F12 查看到封面图片的宽度,不过一般要留大一点,可能有写屏幕大一点避免模糊。
#!/bin/bash
# --- 配置 ---
# 输入文件夹名 (仅在批量模式下生效)
INPUT_DIR="半成品"
# 输出文件夹名
OUTPUT_DIR="output_webp"
# 目标宽度 (高度会按比例自动缩放)
TARGET_WIDTH=570
# WebP 图片质量 (0-100, 推荐 80)
QUALITY=80
# --- 脚本开始 ---
# 创建输出文件夹 (这是一个通用操作,提前执行)
mkdir -p "$OUTPUT_DIR"
# 检查脚本运行时是否带有参数(文件名)
if [ "$#" -gt 0 ]; then
# 如果参数数量大于0,则进入“单独处理模式”
echo "--- 单独处理模式 ---"
echo "准备处理 $# 个指定文件..."
echo ""
# 遍历所有传入的参数(也就是文件名)
for file in "$@"; do
# 检查一下文件是否存在,避免报错
if [ -f "$file" ]; then
# 获取不带路径和扩展名的文件名
filename=$(basename -- "$file")
name_no_ext="${filename%.*}"
echo "正在处理: $filename ..."
# 使用 ffmpeg 进行转换 (核心逻辑和原来一样)
ffmpeg -i "$file" -vf "scale=$TARGET_WIDTH:-1" -q:v "$QUALITY" -y "$OUTPUT_DIR/$name_no_ext.webp"
else
# 如果文件不存在,给个提示
echo "警告: 文件 '$file' 不存在或不是一个文件,已跳过。"
fi
done
else
# 如果参数数量为0(即没有传入任何文件名),则进入原有的“批量模式”
echo "--- 批量处理模式 (处理 '$INPUT_DIR' 文件夹) ---"
echo ""
# 查找所有图片文件并进行转换 (这里的代码和原来完全一样)
find "$INPUT_DIR" -maxdepth 1 -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.bmp" -o -iname "*.tiff" | while read -r file; do
# 获取不带路径和扩展名的文件名
filename=$(basename -- "$file")
name_no_ext="${filename%.*}"
echo "正在处理: $filename ..."
# 使用 ffmpeg 进行转换
ffmpeg -i "$file" -vf "scale=$TARGET_WIDTH:-1" -q:v "$QUALITY" -y "$OUTPUT_DIR/$name_no_ext.webp"
done
fi
echo ""
echo "--- 所有图片处理完成!---"
chmod +x convert.sh # 赋予执行权限
批量重命名
下载下来后图片名都是乱码难以分辨,可以用以下命令将文件夹种的所有图片命名为 1. WebP 2. WebP,方便后续增加图片分辨。
$i = 1; Get-ChildItem | Where-Object { $_.PSIsContainer -eq $false } | ForEach-Object { Rename-Item -Path $_.FullName -NewName "$($i++)$($_.Extension)" }
图片压缩
GitHub - juzisang/picgo-plugin-compress: Image compression plugin for PicGo 这个好久没更新了,用不了 TinyPNG。
然后我在 GitHub issue 区域找到了这个 GitHub - supine0703/picgo-plugin-compress-next: Image compression plugin for PicGo(\>=^2.3.0). Update, adapt and optimize. Better support and richer features,但是也有一年更新了,有个 bug,配置页面没有弹出配置 TinyPNG 的 API 选项。这个 bug 已经被人提交了,但作者应该好久没上线了。
用不了就不用了,最后用了本地压缩。好处就是处理速度快不需要联网。
图片 API
因为我已经有图床了,随机调用图床图片的链接就行了。只需要将链接汇聚起来,做一个随机选择,重定向输出。同时还考虑到防盗链的问题(也许不需要)。
综上考虑做一个 serverless
服务最好,就想到了 Cloudflare
,赛博大善人,用上了它的 worker 服务。
// --- 配置区 ---
// 注意:末尾不要加斜杠 /
const allowedReferer = "https://chifan.de";
// --- API 核心代码 ---
export default {
async fetch(request, env, ctx) {
// 1. 获取请求头中的 'Referer' 信息
const referer = request.headers.get('Referer');
// 2. 防盗链逻辑判断
// (我们允许 referer 为空的情况,这样方便直接在浏览器地址栏测试)
if (referer && !referer.startsWith(allowedReferer)) {
// 返回 403 Forbidden 错误
return new Response(`Hotlinking not allowed. Access denied for referer: ${referer}`, {
status: 403,
statusText: 'Forbidden'
});
}
// 3. 如果通过了防盗链检查,就执行原来的随机图片逻辑
const imageUrls = [
// 在这里粘贴你的图片链接
// 例如:
// "https://example.com/image1.jpg",
// "https://example.com/image2.png"
];
// 从列表中随机选择一个图片链接
const randomIndex = Math.floor(Math.random() * imageUrls.length);
const randomImageUrl = imageUrls[randomIndex];
// 如果图片列表为空或出现意外,返回一个提示
if (!randomImageUrl) {
return new Response('Image URL list is empty or an error occurred.', {
status: 500,
statusText: 'Internal Server Error'
});
}
// 重定向到被选中的图片
return Response.redirect(randomImageUrl, 302);
},
};
评论区(暂无评论)