退化的JPEG
2026年07月17日 JPEG文件的一个酷炫特性是可以选择先保存低频分量。这意味着部分下载的图像将在低分辨率下显示,而不是被截断。在文件中,这通过将压缩数据分成多个“扫描”来实现,每个扫描前面都有一个头部。以下是一个代表性图像的第一个扫描:FF DA - “扫描开始”标记 00 0C - 大端长度字段(12字节)包括自身 03 - 扫描中的通道数(3) 01 - 第一个包含通道的全局ID 00 - 哈夫曼表索引#1(DC:0,AC:0) 02 - 第二个包含通道的全局ID 10 - 哈夫曼表索引#2(DC:1,AC:0) 03 - 第三个包含通道的全局ID 10 - 哈夫曼表索引#2(DC:0,AC:0) 00 - 开始DCT bin(DC) 00 - 结束DCT bin(也是DC) 01 - 精度:半,没有预存的数据。 f8ad 512d d3f1 cd96 - 哈夫曼编码的DCT系数 bcb0 58df 53d5 5d97 [...还有很多更多] ... 这个包含了所有三个颜色通道的最低(DC)傅里叶bin。三个颜色通道是YCbCr,而不是通常的RGB。亮度(Y)分开,因为它必须是高质量的,而颜色可以在视觉上有很多的妥协。非常粗略地:Y = G,Cb = B - G,Cr = R - G 之后,文件还包含另外八个扫描以填充其余的数据: 扫描编号 通道 DCT bin 范围 精度 0 Y Cb Cr 0 - 0 半(-1比特) 1 Y 1 - 5 四分之一(-2比特) 2 Cb 1 - 63 半 3 Cr 1 - 63 半 4 Y 6 - 63 四分之一 5 Y 1 - 63 半 6 Y Cr Cb 0 - 0 全部 7 Cr 1 - 63 全部 8 Cb 1 - 63 全部 9 Y 1 - 63 全部 扫描#0包含图像的非常低分辨率预览。扫描#1添加了一些亮度细节。扫描2到5包含完整的低精度数据。扫描4具有不寻常的光谱范围,因为它填补了#1留下的空白。这样,第5个扫描有完整的四分之一精度数据可供构建。扫描6到9添加了最后缺失的部分,使图像达到全质量。鉴于我提到的颜色不那么重要,可能会觉得我例子中颜色数据优先排列很奇怪:这是因为色度以半分辨率(四分之一像素计数)保存。因此,完整的色度数据(Cr + Cb)只占亮度的一半。由于每个扫描明确设置了其光谱范围,因此应该能够构建一个JPEG文件,其中后续扫描覆盖已经渲染的图像数据。实际上,这很容易做到:将多个具有相同分辨率的图像连接起来,并过滤出图像开始、帧开始和图像结束标记。这可以在十六进制编辑器中完成,但我使用了一个快速简洁的C程序。当在一个慢速网络上提供时,这个连接的文件将切换多个图像:点击在新标签页中打开 但大多数解码器在扫描数量达到一定数量后会放弃:我认为这是为了避免类似ZIP炸弹的问题……但这使得它无法在超过9帧的情况下工作,而这对一个合适的动画来说是不够的。要做到这一点,我必须最小化每帧的扫描数量。最简单的想法是从只包含单个扫描的基线JPEG开始。……但这个不起作用:在渐进模式下,一个扫描不能同时包含AC(大于0的bin)和DC(bin 0)数据。这个限制在基线模式下不存在,但基线解码器在第一个扫描后停止。由于AC数据必须跟随DC数据,因此最小的“渐进”JPEG包含一个仅DC的单一扫描。因为DCT在16x16块上运行,因此这样的图像不会是单一颜色:它的分辨率将是原始分辨率的1/16。 扫描编号 通道 DCT bin 精度 0 Y Cb Cr 0 - 0 全部 这样,我可以让Chrome渲染大约90帧,然后放弃。其他浏览器如Firefox更有耐心,但一个90扫描的图像似乎在几乎所有地方都能正常工作。作为一个额外的好处,这避免了幼稚尝试中的鬼影:那是因为AC扫描应该用于细化旧数据。通常,这允许图像在不膨胀文件大小的情况下包含多个精度级别……但与我的技巧不太兼容。如果文件中只包含没有实际进展的DC扫描,则这不是问题。由于“DC-only”帧是符合标准的图像,因此创建它们并不需要任何特别的东西:cat > frame.scans<<EOF # 仅DC扫描:0,1,2:0-0,0,0; # 以及没有其他 EOF jpegtran -scans frame.scans -outfile out.jpg in.jpg 使用这些,可以将整个视频打包在单个图像中:点击在新标签页中打开 除了非常规的ricksroll和其他恶作剧外,这没有实际应用:没有办法添加定时信息,因此播放完全依赖于网络延迟。……尽管在使用部分渲染时可以获得很多乐趣:这是一个纯HTML视频,使用<dialog>标签:badapple.rose.systems 当然,没有规定数据必须是硬编码的:这是一个不使用CSS或JavaScript的交互式单页应用程序。相关:/projects/bad_j
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡