浏览器有趣的图片解码现象
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
3. 总结一下
图片本身就是上图的状态,只是在 EXIF 信息中又说明了一下 在显示时需要顺时针旋转90°(根据图片元数据可知)。对于我们的观感来说像是被逆时针旋转90°的样子。
4. 疑问
4.1. 在浏览器内为什么会被“校正”?
浏览器直接访问图片资源是通过 HTML 进行渲染,这里起主导作用的是 CSS,
在使用 <img> 元素显示图片时,会有默认参数起到作用。
就是 image-orientation
【用来修正某些图片的预设方向】。
而浏览器内的默认值是 from-image
。
最终呈现给我们的就是图片好像被“校正”过一样。
4.2. 解码方向为什么是从右往左?
chatgpt 提示词:给我科普一下jpeg的解码方向
JPEG 是一种广泛使用的有损图像压缩格式,其解码过程(即从压缩的 JPEG 文件还原出图像)是有一定“方向”的,主要体现在MCU 解码顺序和DCT 数据排列方向这两个方面。下面我从高层到低层帮你梳理 JPEG 的解码方向相关知识。
一、JPEG 解码的基本流程概览
JPEG 解码大致分为以下几个步骤:
- 读取文件头(解析压缩参数,如图像大小、颜色空间、量化表、Huffman 表等)
- Huffman 解码(还原压缩的 DCT 系数)
- 反量化(将 DCT 系数乘以量化表还原)
- 逆 DCT(IDCT)(将频域转换为空域像素值)
- YCbCr 转 RGB(如果使用了 YCbCr 色彩空间)
- 像素重排(按正确顺序排列 MCU,拼接为最终图像)
二、什么是“解码方向”?
在 JPEG 中,“方向”主要指 MCU(最小编码单元)的排列顺序,即:
JPEG 的解码是按照 MCU(Minimum Coded Unit)从左到右、从上到下 的顺序进行的。
也就是说,JPEG 图像的压缩和解码过程是按块(block)从左上角开始,一行一行进行的。
三、解码方向详细拆解
- MCU 的排列顺序(宏观解码方向)
JPEG 图像被划分为 8×8(或 16×16,取决于采样方式)像素大小的最小编码单元(MCU),JPEG 解码器按如下顺序解码:
方向是:水平方向优先,然后垂直方向推进。
- 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 顺序的设计是为了更好地利用图像能量集中在低频区域的特点,从而提高压缩效率。
- 色度子采样与 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
6. 感谢
Ray 的小站:将自适应宽高大小的iframe视频嵌入博客网页
7. 最后
文中图片内容由 腾讯元宝 AI画图 生成
提示词:“关于人工智能的自画像,吉卜力动画风格”