抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

之前在 CSDN 上发表过 制作自己的随机图API,快速、稳定、简易!,主要通过一个简单的 php 脚本部署在服务器上。

这次通过 CloudFlare Worker 实现一个完全无成本的随机图片 API!

图片转 Webp

这步骤可选,转换为 webp 格式后,图片体积压缩而分辨率不变,可以更快地加载。

为了在引用时方便,先把名称按 1、2、3…顺序标号,再通过 PIL 库,将 jpgpng 格式的图片转换成 webp

因为用了文件名按数字排序,所以原始图片需要全为数字,如为其他自行修改代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import os

from PIL import Image


def to_webp(src_dir, dist_dir, img):
img_path = os.path.join(src_dir, img)
dist_path = os.path.join(dist_dir, img.split(".")[0] + ".webp")
if os.path.exists(dist_path):
return
image = Image.open(img_path)
image.save(dist_path, format="webp")
print(img_path + ' convert to ' + dist_path)


def convert(src_dir, dist_dir):
print("Convert: start")
images = os.listdir(src_dir)
images.sort(key=lambda x: int(x[:-4]))
for img in images:
to_webp(src_dir, dist_dir, img)
print("Convert: end")


def rename(dir_path):
print("Rename: start")
num = 1
files = os.listdir(dir_path)
files.sort(key=lambda x: int(x[:-4]))
for file in files:
src_path = os.path.join(dir_path, file)
dist_path = os.path.join(dir_path, str(num)) + os.path.splitext(file)[-1]
num = num + 1
if src_path == dist_path:
# print("Skip: " + src_path)
continue
os.rename(src_path, dist_path)
print(src_path + ' rename to ' + dist_path)
print("Rename: end")


if __name__ == '__main__':
srcDir = r"E:\Onedrive\图片\次元壁纸"
distDir = 'pc'

rename(srcDir)
convert(srcDir, distDir)

文件上传 Github

这步骤不具体说了,图片通过 jsdeliver 引用。

CloudFlare Worker

新建一个 worker,代码参考如下:

  • 因为改了文件名,所以下面只需要修改图片总数 total,就能生成一个随机数访问
  • 个人通过 type 区别宽屏和竖屏图片,自己按需修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
addEventListener('fetch', event => {
event.respondWith(
handleRequest(event.request).catch((err) =>
new Response('cfworker error:\n' + err.stack, {
status: 502,
})
)
);
});

async function handleRequest(request) {
const url = new URL(request.url);
switch (url.pathname) {
case "/img":
var type = url.searchParams.has("type") ? url.searchParams.get("type") : "pc";
const total = getTotal(type);
if (total == 0) return handleImage("pc", getTotal("pc"));
return handleImage(type, total);
case "/favicon.ico":
return fetch("https://gcore.jsdelivr.net/gh/SukiEva/assets/blog/favicon.ico");
default:
return handleNotFound();
}
}

function getTotal(type) {
switch (type) {
case "pc": return 175;
case "mb": return 0;
default: return 0;
}
}

async function handleImage(type, total) {
var index = Math.floor((Math.random() * total)) + 1;
var img = "https://gcore.jsdelivr.net/gh/SukiEva/assets/webp/" + type + "/" + index + ".webp";
res = await fetch(img);
return new Response(res.body, {
headers: {
'content-type': 'image/webp',
},
});
}

function handleNotFound() {
return new Response('Not Found', {
status: 404,
});
}

自定义域名

默认是一个 CF 的域名,但是目前已经被国内 ban 了,需要自行添加域名路由。

  • 添加 DNS A 解析到 2.2.2.2,我配置的 api 三级域名
  • 在 Worker 里面配置路由,比如我的就是 api.sukiu.top/img*

可以通过下面的链接查看实现效果,每天的免费次数是 10w 次,请自行搭建,禁止滥用!!!

评论



Modify from Volantis theme Powered by Hexo