跳到正文
DEV Community· Muhaymin Bin Mehmood·· 3 小時前AI 評分54

下載 WebP 圖片後無法開啟?成因與 3 種處理方法

You Downloaded a .webp and Nothing Opens It. What Happened and 3 Ways Out

AI 導讀

瀏覽器會在圖片請求的 Accept 標頭列出支援格式,圖片 CDN 可據此回傳 WebP,令下載檔案可能與網站上載的原始格式不同。可查看檔案開頭的 RIFF 和 WEBP 確認格式,並嘗試以 Accept: image/jpeg 向 CDN 索取 JPG,或把 WebP 轉成 JPG;需要透明度時則轉成保留 alpha 通道的 PNG。

正文

You see a product photo, right-click, "Save image as", and get image.webp. Your upload form rejects it, an older editor can't open it, and the person you sent it to asks what a WebP is.

The website probably never "uploaded a WebP". Your browser asked for one.

How you ended up with WebP

When a browser requests an image, it sends an Accept header listing formats it understands, including image/webp and often image/avif. Most image CDNs read that header and send the smallest format the browser supports. The store owner uploaded a JPG. The CDN converted it on the fly, and "Save image as" saved what actually arrived.

I wrote about this in more detail in Your Image CDN Picks the Format, including how to see what a CDN really sends.

WebP itself is a good format. Lossy WebP is usually smaller than a JPEG of similar quality, and it supports transparency, which JPEG doesn't. The problem is only compatibility outside the browser: some desktop apps, print services and upload validators still expect JPG or PNG.

Check what the file really is

Extensions lie in both directions. Look at the first 12 bytes:

async function realType(file) {
  const b = new Uint8Array(await file.slice(0, 12).arrayBuffer())
  const s = (i, j) => String.fromCharCode(...b.subarray(i, j))
  if (s(0, 4) === "RIFF" && s(8, 12) === "WEBP") return "webp"
  if (b[0] === 0xff && b[1] === 0xd8 && b[2] === 0xff) return "jpeg"
  if (s(1, 4) === "PNG") return "png"
  if (s(4, 8) === "ftyp") return "heic/avif family" // check the brand at 8-12
  return "unknown"
}

A WebP always starts with RIFF, four size bytes, then WEBP. If your "photo.jpg" starts that way, it's a WebP with the wrong name, and some programs will refuse it for exactly that reason.

Way out 1: ask for a JPG instead

Because the CDN decided by the Accept header, you can often get the original format by asking without WebP in the list. Copy the image address and:

curl -s -o photo.jpg -H "Accept: image/jpeg" "https://example.com/path/to/image"

Then check the bytes with the function above. This works on many CDNs, not all. Some serve WebP whatever you ask, and some URLs point to a WebP original.

Way out 2: convert to JPG

For photos going to upload forms, email or print, JPG is the safe choice. One thing to get right: JPEG has no transparency. Any transparent pixels have to become a colour, and if a converter doesn't choose one, many viewers show them as black. Fill with white first:

async function webpToJpg(file, quality = 0.9) {
  const bitmap = await createImageBitmap(file)
  const canvas = new OffscreenCanvas(bitmap.width, bitmap.height)
  const ctx = canvas.getContext("2d")
  ctx.fillStyle = "#ffffff"
  ctx.fillRect(0, 0, canvas.width, canvas.height)
  ctx.drawImage(bitmap, 0, 0)
  bitmap.close()
  return canvas.convertToBlob({ type: "image/jpeg", quality })
}

Way out 3: convert to PNG when transparency matters

Logos, icons and cut-out product shots often use transparency. Converting those to JPG puts a white box behind them. Use PNG instead: it's lossless and keeps the alpha channel. The file will be bigger than the WebP, sometimes several times bigger, because PNG doesn't use lossy compression. That's the price of an exact copy.

Quick rule:

You have Going to Pick
A photo Form, email, print JPG
A logo or cut-out Editing, design tools PNG
Anything Your own website Keep WebP

If you have many

Converting one file in an editor is fine. For a folder of them, BatchSet has free converters for WebP to JPG (transparent areas filled with white) and WebP to PNG (transparency kept). Both run in the browser, so the images aren't uploaded, and you download everything as one ZIP.

This article was drafted with an AI assistant. The byte check was tested against real WebP, PNG and JPEG files before publishing.

來源:DEV Community · dev.to