跳转至

浏览器有趣的图片解码现象

1. 前提

请观察视频中浏览器加载图片(非原图)时的 解码方向

2. 排查方向

2.1. 文件服务器的HTTP响应体

HTTP响应体并不会明确图片的加载方向(原本猜想是会不会是CDN服务端的策略导致在HTTP响应体进行了配置)。

HTTP/2 200
server: Tengine
content-type: image/jpeg
content-length: 6855128
date: Mon, 12 May 2025 13:39:42 GMT
access-control-allow-credentials: true
access-control-allow-headers: Origin,No-Cache,X-Requested-With,If-Modified-Since,Pragma,Last-Modified,Cache-Control,Expires,Content-Type,Access-Control-Allow-Credentials,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Cache-Webcdn,X-Bilibili-Key-Real-Ip,X-Upos-Auth,Range
access-control-allow-methods: GET, POST, OPTIONS
access-control-allow-origin: *
access-control-expose-headers: Content-Length,X-Cache-Webcdn,Content-Type,Content-Length,Content-Md5,X-Bili-Trace-Id
cache-control: max-age=31536000
code: 200
content-md5: h+24Y9yfYYhk/JuPQzD4kA==
cross-origin-resource-policy: cross-origin
etag: 60750d6e34f0aa12eb180fb731d8c80880e2c4ff
expires: Tue, 12 May 2026 21:38:15 GMT
last-modified: Mon, 12 May 2025 13:38:14 GMT
vary: Accept-Encoding,Origin,X1-Bilispy-Color
x-amz-request-id: 1747057095850664020
x-amz-version-id: v1.0.0
x-bili-trace-id: 1c585c364da63a7e147ccf65d16821fa
x-hyper-traffic-cache-state: hit
via: cache27.l2cn3130[0,0,200-0,H], cache22.l2cn3130[1,0], vcache22.cn5804[0,0,200-0,H], vcache27.cn5804[2,0]
age: 75441
ali-swift-global-savetime: 1747057182
x-cache: HIT TCP_HIT dirn:10:94267133
x-swift-savetime: Mon, 12 May 2025 13:55:57 GMT
x-swift-cachetime: 31535025
x-edge-server-addr: ***.***.***.***
x-cache-webcdn: AL
timing-allow-origin: *
eagleid: 79117baf17471326239665979e

2.2. CSS设置(后续另说)

虽然在源站(B站视频评论区)发现这种情况,但是测试时我是直接在浏览器新标签页中访问图片源并打开查看的,并没有特殊的CSS参数设置,也出现了同样的现象。

2.3. 图片格式 jpeg

EXIF信息查看工具,发现 EXIF 信息中带有标签 Orientation: Rotate 90 CW

2025-05-18-2-3

3. 总结一下

图片本身就是上图的状态,只是在 EXIF 信息中又说明了一下 在显示时需要顺时针旋转90°(根据图片元数据可知)。对于我们的观感来说像是被逆时针旋转90°的样子。

4. 疑问

4.1. 在浏览器内为什么会被“校正”?

浏览器直接访问图片资源是通过 HTML 进行渲染,这里起主导作用的是 CSS, 在使用 <img> 元素显示图片时,会有默认参数起到作用。 就是 image-orientation【用来修正某些图片的预设方向】。 而浏览器内的默认值是 from-image。 最终呈现给我们的就是图片好像被“校正”过一样。

2025-05-18-4-1-1.jpg

2025-05-18-4-1-2.jpg

4.2. 解码方向为什么是从右往左?

chatgpt 提示词:给我科普一下jpeg的解码方向

JPEG 是一种广泛使用的有损图像压缩格式,其解码过程(即从压缩的 JPEG 文件还原出图像)是有一定“方向”的,主要体现在MCU 解码顺序DCT 数据排列方向这两个方面。下面我从高层到低层帮你梳理 JPEG 的解码方向相关知识。


一、JPEG 解码的基本流程概览

JPEG 解码大致分为以下几个步骤:

  1. 读取文件头(解析压缩参数,如图像大小、颜色空间、量化表、Huffman 表等)
  2. Huffman 解码(还原压缩的 DCT 系数)
  3. 反量化(将 DCT 系数乘以量化表还原)
  4. 逆 DCT(IDCT)(将频域转换为空域像素值)
  5. YCbCr 转 RGB(如果使用了 YCbCr 色彩空间)
  6. 像素重排(按正确顺序排列 MCU,拼接为最终图像)

二、什么是“解码方向”?

在 JPEG 中,“方向”主要指 MCU(最小编码单元)的排列顺序,即:

JPEG 的解码是按照 MCU(Minimum Coded Unit)从左到右、从上到下 的顺序进行的。

也就是说,JPEG 图像的压缩和解码过程是按块(block)从左上角开始,一行一行进行的


三、解码方向详细拆解

  1. MCU 的排列顺序(宏观解码方向)

JPEG 图像被划分为 8×8(或 16×16,取决于采样方式)像素大小的最小编码单元(MCU),JPEG 解码器按如下顺序解码:

(0,0) → (1,0) → (2,0) → ...(一行)
 ↓        ↓        ↓
(0,1) → (1,1) → (2,1) → ...(下一行)
...

方向是:水平方向优先,然后垂直方向推进

  1. MCU 内的 DCT 系数顺序(微观方向)

在每个 8x8 的 block 内,JPEG 使用 Zig-Zag 扫描顺序 读取和压缩 64 个 DCT 系数:

 0  1  5  6 14 15 27 28
 2  4  7 13 16 26 29 42
 3  8 12 17 25 30 41 43
 9 11 18 24 31 40 44 53
10 19 23 32 39 45 52 54
20 22 33 38 46 51 55 60
21 34 37 47 50 56 59 61
35 36 48 49 57 58 62 63

Zig-Zag 顺序的设计是为了更好地利用图像能量集中在低频区域的特点,从而提高压缩效率。

  1. 色度子采样与 MCU 内部顺序

例如,在 4:2:0 的采样格式中,一个 MCU 由以下组成:

  • 4 个 Y(亮度)8×8 块
  • 1 个 Cb(蓝色差)8×8 块
  • 1 个 Cr(红色差)8×8 块

这些块也是按照固定顺序排列解码的(如先 4 个 Y,再 Cr、Cb),顺序会在 JPEG 的帧头中指定。


四、总结:JPEG 解码方向关键点

项目 解码方向/顺序
MCU 解码顺序 从左到右,从上到下
DCT 系数排列 Zig-Zag 扫描(低频 → 高频)
色度块顺序 按照帧头定义的通道顺序
最终像素拼接顺序 按照 MCU 顺序依次拼接

图片只是被 CSS 修正了方向,并不会影响 解码方向。

4.3. 什么情况下会出现这种现象?

在使用手机或者照相机拍摄照片时,就有可能会被附加上 EXIF 标签参数 Orientation。是开发者让这类应用更加 elegant 和 for humans。

5. 参考

Chrome Image EXIF Orientation Issue

Correct image orientation for images - Chrome 81

image-orientation

图像元数据(Metadata)及 Exif信息分析

6. 感谢

Ray 的小站:将自适应宽高大小的iframe视频嵌入博客网页

7. 最后

文中图片内容由 腾讯元宝 AI画图 生成

提示词:“关于人工智能的自画像,吉卜力动画风格”