import{_ as n,c as t,a,b as Q,d as m,o as l}from"./app-DPgwpJxh.js";const r="/images/2014/08/Lenna.png",d="/images/2014/08/jpeg_01.jpg",s="/images/2014/08/RGB_YCBCR.png",e="/images/2014/08/jpeg_14.jpg",o="/images/2014/08/jpeg_15.jpg",H="/images/2014/08/jpeg_16.png",g="/images/2014/08/jpeg_17.png",p="/images/2014/08/jpeg_18.png",h={},i={class:"MathJax",jax:"SVG",style:{position:"relative"}},L={style:{"vertical-align":"-0.373ex"},xmlns:"http://www.w3.org/2000/svg",width:"3.323ex",height:"1.918ex",role:"img",focusable:"false",viewBox:"0 -683 1468.7 847.8","aria-hidden":"true"},M={class:"MathJax",jax:"SVG",style:{position:"relative"}},f={style:{"vertical-align":"-0.339ex"},xmlns:"http://www.w3.org/2000/svg",width:"3.323ex",height:"1.885ex",role:"img",focusable:"false",viewBox:"0 -683 1468.7 833","aria-hidden":"true"},c={class:"MathJax",jax:"SVG",display:"true",style:{position:"relative"}},V={style:{"vertical-align":"-0.566ex"},xmlns:"http://www.w3.org/2000/svg",width:"42.105ex",height:"2.262ex",role:"img",focusable:"false",viewBox:"0 -750 18610.4 1000","aria-hidden":"true"},Z={class:"MathJax",jax:"SVG",style:{position:"relative"}},u={style:{"vertical-align":"-0.373ex"},xmlns:"http://www.w3.org/2000/svg",width:"11.494ex",height:"1.918ex",role:"img",focusable:"false",viewBox:"0 -683 5080.2 847.8","aria-hidden":"true"},w={class:"MathJax",jax:"SVG",style:{position:"relative"}},x={style:{"vertical-align":"-0.339ex"},xmlns:"http://www.w3.org/2000/svg",width:"11.494ex",height:"1.885ex",role:"img",focusable:"false",viewBox:"0 -683 5080.2 833","aria-hidden":"true"},b={class:"MathJax",jax:"SVG",display:"true",style:{position:"relative"}},D={style:{"vertical-align":"-0.186ex"},xmlns:"http://www.w3.org/2000/svg",width:"30.949ex",height:"1.781ex",role:"img",focusable:"false",viewBox:"0 -705 13679.4 787","aria-hidden":"true"},v={class:"MathJax",jax:"SVG",display:"true",style:{position:"relative"}},y={style:{"vertical-align":"-2.27ex"},xmlns:"http://www.w3.org/2000/svg",width:"18.045ex",height:"5.959ex",role:"img",focusable:"false",viewBox:"0 -1630.8 7975.8 2634","aria-hidden":"true"},C={class:"MathJax",jax:"SVG",display:"true",style:{position:"relative"}},j={style:{"vertical-align":"-2.31ex"},xmlns:"http://www.w3.org/2000/svg",width:"18.08ex",height:"6ex",role:"img",focusable:"false",viewBox:"0 -1630.8 7991.4 2651.8","aria-hidden":"true"},E={class:"MathJax",jax:"SVG",display:"true",style:{position:"relative"}},B={style:{"vertical-align":"-3.507ex"},xmlns:"http://www.w3.org/2000/svg",width:"33.51ex",height:"8.145ex",role:"img",focusable:"false",viewBox:"0 -2050 14811.3 3600","aria-hidden":"true"};function G(k,T){return l(),t("div",null,[T[28]||(T[28]=a('

JPEG算法解密(一)

图片压缩有多重要,可能很多人可能并没有一个直观上的认识,举个例子,一张800X800大小的普通图片,如果未经压缩,大概在1.7MB左右,这个体积如果存放文本文件的话足够保存一部92万字的鸿篇巨著《红楼梦》,现如今互联网上绝大部分图片都使用了JPEG压缩技术,也就是大家使用的jpg文件,通常JPEG文件相对于原始图像,能够得到1/8的压缩比,如此高的压缩率是如何做到的呢?
JPEG能够获得如此高的压缩比是因为使用了有损压缩技术,所谓有损压缩,就是把原始数据中不重要的部分去掉,以便可以用更小的体积保存,这个原理其实很常见,比如485194.200000000001这个数,如果我们用485194.2来保存,就是一种“有损”的保存方法,因为小数点后面的那个“0.000000000001”属于不重要的部分,所以可以被忽略掉。JPEG整个压缩过程基本上也是遵循这个步骤:

  1. 把数据分为“重要部分”和“不重要部分”
  2. 滤掉不重要的部分
  3. 保存

步骤一:图像分割


JPEG算法的第一步,图像被分割成大小为8X8的小块,这些小块在整个压缩过程中都是单独被处理的。后面我们会以一张非常经典的图为例,这张图片名字叫做Lenna,据说是世界上第一张JPG图片,这张图片自从诞生之日开始,就和图像处理结下渊源,陪伴了无数理工宅男度过了的一个个不眠之夜,可谓功勋卓著,感兴趣的朋友可以在这里了解到这张图片的故事。

步骤二:颜色空间转换RGB->YCbCr


所谓“颜色空间”,是指表达颜色的数学模型,比如我们常见的“RGB”模型,就是把颜色分解成红绿蓝三种分量,这样一张图片就可以分解成三张灰度图,数学表达上,每一个8X8的图案,可以表达成三个8X8的矩阵,其中的数值的范围一般在[0,255]之间。

',11)),Q("p",null,[T[4]||(T[4]=m("不同的颜色模型各有不同的应用场景,例如RGB模型适合于像显示器这样的自发光图案,而在印刷行业,使用油墨打印,图案的颜色是通过在反射光线时产生的,通常使用CMYK模型,而在JPEG压缩算法中,需要把图案转换成为YCbCr模型,这里的Y表示亮度(Luminance),Cb和Cr分别表示绿色和红色的“色差值”。")),T[5]||(T[5]=Q("br",null,null,-1)),T[6]||(T[6]=m(" “色差”这个概念起源于电视行业,最早的电视都是黑白的,那时候传输电视信号只需要传输亮度信号,也就是Y信号即可,彩色电视出现之后,人们在Y信号之外增加了两条色差信号以传输颜色信息,这么做的目的是为了兼容黑白电视机,因为黑白电视只需要处理信号中的Y信号即可。")),T[7]||(T[7]=Q("br",null,null,-1)),T[8]||(T[8]=m(" 根据三基色原理,人们发现红绿蓝三种颜色所贡献的亮度是不同的,绿色的“亮度”最大,蓝色最暗,设红色所贡献的亮度的份额为")),Q("mjx-container",i,[(l(),t("svg",L,T[0]||(T[0]=[a('',1)]))),T[1]||(T[1]=Q("mjx-assistive-mml",{unselectable:"on",display:"inline"},[Q("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"R")])])],-1))]),T[9]||(T[9]=m(",蓝色贡献的份额为")),Q("mjx-container",M,[(l(),t("svg",f,T[2]||(T[2]=[a('',1)]))),T[3]||(T[3]=Q("mjx-assistive-mml",{unselectable:"on",display:"inline"},[Q("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"B")])])],-1))]),T[10]||(T[10]=m(",那么亮度为"))]),Q("mjx-container",c,[(l(),t("svg",V,T[11]||(T[11]=[a('',1)]))),T[12]||(T[12]=Q("mjx-assistive-mml",{unselectable:"on",display:"block"},[Q("math",{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},[Q("mi",null,"Y"),Q("mo",null,"="),Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"R")]),Q("mo",null,"⋅"),Q("mi",null,"R"),Q("mo",null,"+"),Q("mo",{stretchy:"false"},"("),Q("mn",null,"1"),Q("mo",null,"−"),Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"R")]),Q("mo",null,"−"),Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"B")]),Q("mo",{stretchy:"false"},")"),Q("mo",null,"⋅"),Q("mi",null,"G"),Q("mo",null,"+"),Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"B")]),Q("mo",null,"⋅"),Q("mi",null,"B")])],-1))]),Q("p",null,[T[17]||(T[17]=m("根据经验,")),Q("mjx-container",Z,[(l(),t("svg",u,T[13]||(T[13]=[a('',1)]))),T[14]||(T[14]=Q("mjx-assistive-mml",{unselectable:"on",display:"inline"},[Q("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"R")]),Q("mo",null,"="),Q("mn",null,"0.299")])],-1))]),T[18]||(T[18]=m(",")),Q("mjx-container",w,[(l(),t("svg",x,T[15]||(T[15]=[a('',1)]))),T[16]||(T[16]=Q("mjx-assistive-mml",{unselectable:"on",display:"inline"},[Q("math",{xmlns:"http://www.w3.org/1998/Math/MathML"},[Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"B")]),Q("mo",null,"="),Q("mn",null,"0.114")])],-1))]),T[19]||(T[19]=m(",那么"))]),Q("mjx-container",b,[(l(),t("svg",D,T[20]||(T[20]=[a('',1)]))),T[21]||(T[21]=Q("mjx-assistive-mml",{unselectable:"on",display:"block"},[Q("math",{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},[Q("mi",null,"Y"),Q("mo",null,"="),Q("mn",null,"0.299"),Q("mi",null,"R"),Q("mo",null,"+"),Q("mn",null,"0.587"),Q("mi",null,"G"),Q("mo",null,"+"),Q("mn",null,"0.114"),Q("mi",null,"B")])],-1))]),T[29]||(T[29]=Q("p",null,"蓝色和红色的色差的定义如下",-1)),Q("mjx-container",v,[(l(),t("svg",y,T[22]||(T[22]=[a('',1)]))),T[23]||(T[23]=Q("mjx-assistive-mml",{unselectable:"on",display:"block"},[Q("math",{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},[Q("msub",null,[Q("mi",null,"C"),Q("mi",null,"b")]),Q("mo",null,"="),Q("mstyle",{mathsize:"1.2em"},[Q("mrow",{"data-mjx-texclass":"ORD"},[Q("mfrac",null,[Q("mn",null,"1"),Q("mn",null,"2")]),Q("mfrac",null,[Q("mrow",null,[Q("mi",null,"B"),Q("mo",null,"−"),Q("mi",null,"Y")]),Q("mrow",null,[Q("mn",null,"1"),Q("mo",null,"−"),Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"B")])])])])])])],-1))]),Q("mjx-container",C,[(l(),t("svg",j,T[24]||(T[24]=[a('',1)]))),T[25]||(T[25]=Q("mjx-assistive-mml",{unselectable:"on",display:"block"},[Q("math",{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},[Q("msub",null,[Q("mi",null,"C"),Q("mi",null,"r")]),Q("mo",null,"="),Q("mstyle",{mathsize:"1.2em"},[Q("mrow",{"data-mjx-texclass":"ORD"},[Q("mfrac",null,[Q("mn",null,"1"),Q("mn",null,"2")]),Q("mfrac",null,[Q("mrow",null,[Q("mi",null,"R"),Q("mo",null,"−"),Q("mi",null,"Y")]),Q("mrow",null,[Q("mn",null,"1"),Q("mo",null,"−"),Q("msub",null,[Q("mi",null,"K"),Q("mi",null,"R")])])])])])])],-1))]),T[30]||(T[30]=Q("p",null,"最终可以得到RGB转换为YCbCr的数学公式为",-1)),Q("mjx-container",E,[(l(),t("svg",B,T[26]||(T[26]=[a('',1)]))),T[27]||(T[27]=Q("mjx-assistive-mml",{unselectable:"on",display:"block"},[Q("math",{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},[Q("mtable",{displaystyle:"true",columnalign:"right left",columnspacing:"0em",rowspacing:"3pt"},[Q("mtr",null,[Q("mtd",null,[Q("mi",null,"Y")]),Q("mtd",null,[Q("mi"),Q("mo",null,"="),Q("mn",null,"0.299"),Q("mi",null,"R"),Q("mo",null,"+"),Q("mn",null,"0.5870"),Q("mi",null,"G"),Q("mo",null,"+"),Q("mn",null,"0.114"),Q("mi",null,"B")])]),Q("mtr",null,[Q("mtd",null,[Q("msub",null,[Q("mi",null,"C"),Q("mi",null,"b")])]),Q("mtd",null,[Q("mi"),Q("mo",null,"="),Q("mo",null,"−"),Q("mn",null,"0.1687"),Q("mi",null,"R"),Q("mo",null,"−"),Q("mn",null,"0.3313"),Q("mi",null,"G"),Q("mo",null,"+"),Q("mn",null,"0.5"),Q("mi",null,"B")])]),Q("mtr",null,[Q("mtd",null,[Q("msub",null,[Q("mi",null,"C"),Q("mi",null,"r")])]),Q("mtd",null,[Q("mi"),Q("mo",null,"="),Q("mn",null,"0.5"),Q("mi",null,"R"),Q("mo",null,"−"),Q("mn",null,"0.4187"),Q("mi",null,"G"),Q("mo",null,"−"),Q("mn",null,"0.0813"),Q("mi",null,"B")])])])])],-1))]),T[31]||(T[31]=a('

YCbCr模型广泛应用在图片和视频的压缩传输中,比如你可以留意一下电视或者DVD后面的接口,就可以发现色差接口。

这是有道理的,还记得我们在文章开始时提到的有损压缩的基本原理吗?有损压缩首先要做的事情就是“把重要的信息和不重要的信息分开”,YCbCr恰好能做到这一点。对于人眼来说,图像中明暗的变化更容易被感知到,这是由于人眼的构造引起的。视网膜上有两种感光细胞,能够感知亮度变化的视杆细胞,以及能够感知颜色的视锥细胞,由于视杆细胞在数量上远大于视锥细胞,所以我们更容易感知到明暗细节。比如说下面这张图

Y
Cb
Cr
可以明显看到,亮度图的细节更加丰富。JPEG把图像转换为YCbCr之后,就可以针对数据得重要程度的不同做不同的处理。这就是为什么JPEG使用这种颜色空间的原因。 ',5))])}const R=n(h,[["render",G],["__file","JPEG001.html.vue"]]),P=JSON.parse('{"path":"/blog/2025/02/JPEG001.html","title":"JPEG算法解密(一)","lang":"zh-CN","frontmatter":{"title":"JPEG算法解密(一)","tags":"压缩 图像 程序 算法","next":{"text":"JPEG算法解密(二)","link":"JPEG002.md"}},"headers":[{"level":3,"title":"步骤一:图像分割","slug":"步骤一-图像分割","link":"#步骤一-图像分割","children":[]},{"level":3,"title":"步骤二:颜色空间转换RGB->YCbCr","slug":"步骤二-颜色空间转换rgb-ycbcr","link":"#步骤二-颜色空间转换rgb-ycbcr","children":[]}],"git":{},"filePathRelative":"blog/2025/02/JPEG001.md"}');export{R as comp,P as data};