You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cloudflare Workers中获取图片尺寸?解决Image未定义报错

解决Cloudflare Worker中无法使用Image/createImageBitmap获取图片宽高的问题

问题原因

Cloudflare Worker运行在无DOM的V8隔离环境中,Image、createImageBitmap这类浏览器专属的DOM API并不存在,直接调用会抛出ReferenceError。获取图片宽高无需渲染图片,解析图片文件的元数据即可实现。

解决方案1:纯JS解析图片文件头(无外部依赖)

通过读取图片的ArrayBuffer,解析PNG、JPEG等常见格式的文件头元数据获取宽高,适合轻量场景:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const imageUrl = new URL(request.url).searchParams.get('imageUrl')
  if (!imageUrl) {
    return new Response(JSON.stringify({ error: '缺少imageUrl参数' }), {
      headers: { 'content-type': 'application/json' },
      status: 400
    })
  }

  try {
    const response = await fetch(imageUrl)
    const arrayBuffer = await response.arrayBuffer()
    const { width, height } = getImageDimensions(arrayBuffer)
    
    return new Response(JSON.stringify({ width, height }), {
      headers: { 'content-type': 'application/json' }
    })
  } catch (err) {
    return new Response(JSON.stringify({ error: err.message }), {
      headers: { 'content-type': 'application/json' },
      status: 500
    })
  }
}

function getImageDimensions(arrayBuffer) {
  const view = new DataView(arrayBuffer)
  
  // 检测PNG格式
  if (view.getUint8(0) === 0x89 && view.getUint8(1) === 0x50 && view.getUint8(2) === 0x4E && view.getUint8(3) === 0x47) {
    return {
      width: view.getUint32(16, false),
      height: view.getUint32(20, false)
    }
  }
  
  // 检测JPEG格式
  if (view.getUint8(0) === 0xFF && view.getUint8(1) === 0xD8) {
    let offset = 2
    while (offset < view.byteLength) {
      if (view.getUint8(offset) !== 0xFF) break
      const marker = view.getUint8(offset + 1)
      // 匹配包含尺寸信息的JPEG标记段
      if ((marker >= 0xC0 && marker <= 0xC3) || (marker >= 0xC5 && marker <= 0xC7) || (marker >= 0xC9 && marker <= 0xCB) || (marker >= 0xCD && marker <= 0xCF)) {
        return {
          height: view.getUint16(offset + 5, false),
          width: view.getUint16(offset + 7, false)
        }
      }
      const segmentLength = view.getUint16(offset + 2, false)
      offset += segmentLength + 2
    }
  }
  
  throw new Error('不支持的图片格式或解析失败')
}

解决方案2:使用第三方库(支持更多格式)

如果需要支持WebP、GIF等更多格式,可使用image-size库,它能纯JS解析多种图片的元数据:

  1. 初始化项目并安装依赖:
npm init -y
npm install image-size
  1. 修改代码为ES模块形式:
import sizeOf from 'image-size'

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const imageUrl = new URL(request.url).searchParams.get('imageUrl')
  if (!imageUrl) {
    return new Response(JSON.stringify({ error: '缺少imageUrl参数' }), {
      headers: { 'content-type': 'application/json' },
      status: 400
    })
  }

  try {
    const response = await fetch(imageUrl)
    const arrayBuffer = await response.arrayBuffer()
    const dimensions = sizeOf(arrayBuffer)
    
    return new Response(JSON.stringify({ width: dimensions.width, height: dimensions.height }), {
      headers: { 'content-type': 'application/json' }
    })
  } catch (err) {
    return new Response(JSON.stringify({ error: err.message }), {
      headers: { 'content-type': 'application/json' },
      status: 500
    })
  }
}
  1. 用wrangler工具打包部署即可,Cloudflare Worker支持该库的ES模块导入。

内容的提问来源于stack exchange,提问作者Marcel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:20:17