JPEG图片文件格式浅析,以及使用C#实现图片的解析

JPEG是网络中使用非常频繁的一种图片,本身是一种有损压缩格式,本文并不对其压缩和编码进行研究,只是对JPEG的文件存储格式进行浅析,然后说明在C#中实现对其存储数据的解析。JPEG是按段存储的,在真正的图像数据之前会有多个段用来存储图片的信息,在SOS(Start of Scan)段之后之后开始扫面压缩的图像数据,最后遇到EOI(End of Image)段停止。除SOI(Start o
摘要由CSDN通过智能技术生成

JPEG是网络中使用非常频繁的一种图片,本身是一种有损压缩格式,本文并不对其压缩和编码进行研究,只是对JPEG的文件存储格式进行浅析,然后说明在C#中实现对其存储数据的解析。
JPEG是按段存储的,在真正的图像数据之前会有多个段用来存储图片的信息,在SOSStart of Scan)段之后之后开始扫面压缩的图像数据,最后遇到EOIEnd of Image)段停止。
SOIStart of Image)段和EOI段外,JPEG的每个段都是由两部分组成:标记码(Tag)和段内数据:其中,标记码的长度为2个字节,第一个字节(高位字节)为0xFF,通常标志一个段的开始,第二个字节是该段的标志字节,用来标明该段的身份,对于不同的段,该字节的值是不同的;在标记码之后就是段内数据,段内数据的前两个字节用来定义该段的长度(注意,该长度不包括Tag的两个字节)。
注意:对于JPEG格式的图片,可以再段与段之间填充多个值为0xFF的字节,在进行图片解析时,这些字节是被忽略的。
对于JPEG来说,其真正的图像数据是位于SOS(start of Scan)段和EOI段之间的,所以对读取的图片字节流进行拆分时,可以从EOI段开始,获取SOS之前(包括SOS)各段的数据,获取的方法是首先定位标志位,然后再标志位后获取长度,然后按照长度读取出该段,然后继续寻找下一个段的标志位(此处必须注意的是在两个段之间可能会填充不定长个值为0xFF的字节),直到得到SOS段。在SOS段后便是图片的压缩数据,直接进行扫描,直到扫描到EOI段的Tag。

相关代码如下,在下面的代码中,首先通过file的方法或者filestream将图片作为字节流读入,然后进行处理:

代码中并没有把每个段切出来,只是在for循环中对如果定位每个段给出了方案,直到得到SOS段

之后,在下一个for循环中扫描数据直到扫描到EOI段 停止

int eoi= 0;
            int sos = 0;
            //找到jpeg图片sos段的结尾
            for (int i = 2; i < allGetBytes.Length; i++)
            {
                if (allGetBytes.ElementAt(i) == 255 & allGetBytes.ElementAt(i + 1) == 218)
                {
                    sos = i + 1;
                    break;
                }
                if (allGetBytes.ElementAt(i) == 255 && allGetBytes.ElementAt(i + 1) == 255)
                {
                    continue;
                }
                if (allGetBytes.ElementAt(i) == 255 && allGetBytes.ElementAt(i + 1) != 255) 
                {
                    int count = 0;
                    count += allGetBytes.ElementAt(i + 2);
                    count = count * 16 * 16 + allGetBytes.ElementAt(i + 3);
                    i += (count + 1);
                    continue;
                }
                
          }
         //在sos段后遍历搜索EOI结束段
          for (int i = sos; i < allGetBytes.Length; i++)
          {
              if (allGetBytes.ElementAt(i) == 255 && allGetBytes.ElementAt(i + 1) == 217)
                { 
                    eoi = i+1;
                    break;
                }
          }



最后来就说一下在

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值