/**
* Fetch and log a request
* @param {Request} request
*/
export default {
async fetch(request) {
// Parse request URL to get access to query string
let url = new URL(request.url)
// Cloudflare-specific options are in the cf object.
let options = { cf: { image: {} } }
// Copy parameters from query string to request options.
// You can implement various different parameters here.
if (url.searchParams.has("fit")) options.cf.image.fit = url.searchParams.get("fit")
if (url.searchParams.has("width")) options.cf.image.width = url.searchParams.get("width")
if (url.searchParams.has("height")) options.cf.image.height = url.searchParams.get("height")
if (url.searchParams.has("quality")) options.cf.image.quality = url.searchParams.get("quality")
// Your Worker is responsible for automatic format negotiation. Check the Accept header.
const accept = request.headers.get("Accept");
if (/image\/avif/.test(accept)) {
options.cf.image.format = 'avif';
} else if (/image\/webp/.test(accept)) {
options.cf.image.format = 'webp';
}
// Get URL of the original (full size) image to resize.
// You could adjust the URL here, e.g., prefix it with a fixed address of your server,
// so that user-visible URLs are shorter and cleaner.
const imageURL = url.searchParams.get("image")
if (!imageURL) return new Response('Missing "image" value', { status: 400 })
try {
// TODO: Customize validation logic
const { hostname, pathname } = new URL(imageURL)
// Optionally, only allow URLs with JPEG, PNG, GIF, or WebP file extensions
// @see https://developers.cloudflare.com/images/url-format#supported-formats-and-limitations
if (!/\.(jpe?g|png|gif|webp)$/i.test(pathname)) {
return new Response('Disallowed file extension', { status: 400 })
}
// Demo: Only accept "example.com" images
if (hostname !== 'example.com') {
return new Response('Must use "example.com" source images', { status: 403 })
}
} catch (err) {
return new Response('Invalid "image" value', { status: 400 })
}
// Build a request that passes through request headers
const imageRequest = new Request(imageURL, {
headers: request.headers
})
// Returning fetch() with resizing options will pass through response with the resized image.
return fetch(imageRequest, options)
}
}
效果:
原图:

压缩后:

体积对比:

搬运自:https://developers.cloudflare.com/images/transform-images/transform-via-workers/
https://github.com/0-RTT/telegraph
我的图床项目是直接在前端压缩,感觉这个更方便点。
@应无所住 #1 我是觉得,存储得是原图,展示可选原图和压缩后的
我用的
webp.se
方便
@若如初见 #3 哈哈哈我是集成到博客上的
用worker转码和压缩,是很好的办法
可以避免很多转码漏洞,还有一些svg的针对攻击
据我所知,v2ex站自建了图像转码微服务
@Flare #5 是的,只能说 cf 活菩萨
@vlvie #6
Cf Image以前是收费的,现在免费了一些额度
我安装官方示例配置,将format设置为avif
let options = { cf: { image: {quality: 80, format: "avif"} } }但是生成的还是jpg格式的图片
我查看文档, 发现要开启 cf 控制台 images 中的转换才能变格式 (并且转换需要绑定一个域名)
于是我开启转换并设置路由到我的域名上
这时候的确是可以转换了, 但是生成的是webp
在代码中已经设置格式为avif ,生成的还是webp
请问楼主是如何部署的, 能够生成avif?
@三七 #8
要指定就是
按理说你设置的也没错啊
官方的说明:https://developers.cloudflare.com/images/transform-images/transform-via-workers/#format
@vlvie #9
我测试了一个下午发现了原因
Cloudflare还是太鸡贼了
虽然免费压缩
但是他也挺小气的
总的来说, 压缩分为3种(优先于你预设的格式)
jpg webp avif
经过我一个下午的测试
avif 和 webp 之间的界限是316w像素
只有图片小于等于316w像素时, 才会激活avif压缩