zoukankan      html  css  js  c++  java
  • Windows Phone 解析图片尺寸之jpg

      上一篇介绍了Windows Phone 解析图片尺寸之png,本篇介绍一下如何解析jpg图片的尺寸大小,由于jpg图片的格式相对于png要复杂很多,所以首先我们要先清楚的了解jpg图片的数据格式,jpg图片包括SOI和数据两个部分。
      SOI,Start of Image,图像开始,标记代码 2字节 固定值0xFFD8。
      数据部分分成很多数据段,数据段的一般结构如下。

    段数据结构
    名称 字节 说明
    段标识 >= 1 多于一个的0xFF
    段类型 1 类型编码(称作“标记码”)
    段长度 2 包括段内容和段长度本身,不包括段标识和段类型
    短内容 <= 65533  

      段类型有30种,但只有10种是必须被所有程序识别的,其它的类型都可以忽略。在这么多的段中,其中JPG图片的尺寸相关信息存储在SOF0(图像基本信息)段中。所以需要详细了解一下SOFO段的数据结构。

    SOFO段结构
    名称 字节 说明
    段标识 1 0XFF
    段类型 1 0XCO JFIF格式的为0XC2
    段长度 2 其值=8+组件数量×3
    样本精度 1 8 每个样本位数(大多数软件不支持12和16)
    图片高的 2 采用Motorola格式,即:高位在前,低位在后
    图片宽度 2 采用Motorola格式,即:高位在前,低位在后

      由于我们是为了解析JPG图片的宽度和高度信息,所以上表SOFO段结构只列出了到宽度为止结构信息,接下来还有其他一些图片的相关信息,这里就不再列出。
      根据上面对JPG图片格式的解析,我们可以分一下几步来解析JPG图片的尺寸信息。
      1.读取2个字节的SOI,即0xFFD8,根据这两个字节判断图片是否为JPG图片,如果不是,则退出解析过程。

    View Code
            //读取2个字节的SOI,即0xFFD8
    byte[] header = new byte[2];
    stream.Read(header, 0, 2);
    //判断是否为JPG,不是退出解析
    if (!(header[0] == 0xFF &&
    header[1] == 0xD8))
    {
    //不是JPG图片
    return;
    }

      2.接下来就需要解析图片的数据部分,由于数据部分是有很多不同的数据段构成,数据段拥有一些共同的特性,所以这里我们需要做一个循环来逐个遍历查找到SOFO数据段。

    View Code
            //段类型
    int type = -1;
    int ff = -1;
    //记录当前读取的位置
    long ps = 0;
    //逐个遍历所以段,查找SOFO段
    do
    {
    do
    {
    //每个新段的开始标识为oxff,查找下一个新段
    ff = stream.ReadByte();
    if (ff < 0) //文件结束
    {
    return;
    }
    } while (ff != 0xff);

    do
    {
    //段与段之间有一个或多个oxff间隔,跳过这些oxff之后的字节为段标识
    type = stream.ReadByte();
    } while (type == 0xff);

    //记录当前位置
    ps = stream.Position;
    switch (type)
    {
    case 0x00:
    case 0x01:
    case 0xD0:
    case 0xD1:
    case 0xD2:
    case 0xD3:
    case 0xD4:
    case 0xD5:
    case 0xD6:
    case 0xD7:
    break;
    case 0xc0: //SOF0段(图像基本信息)
    case 0xc2: //JFIF格式的 SOF0段
    {
    //找到SOFO段,解析宽度和高度信息
    getJpgSize(stream);
    return;
    }
    default: //别的段都跳过
    //获取段长度,直接跳过
    ps = stream.ReadByte() * 256;
    ps = stream.Position + ps + stream.ReadByte() - 2;
    break;
    }
    if (ps + 1 >= stream.Length) //文件结束
    {
    return;
    }
    stream.Position = ps; //移动指针
    } while (type != 0xda); // 扫描行开始

      3.找到SOFO数据段后,就可以解析图片的宽度和高度信息。

    View Code
            /// <summary>
    /// 解析JPG图片的尺寸
    /// </summary>
    /// <param name="stream"></param>
    private void getJpgSize(Stream stream)
    {
    //跳过2个自己长度信息和1个字节的精度信息
    stream.Seek(3, SeekOrigin.Current);

    //高度 占2字节 低位高位互换
    height_ = stream.ReadByte() * 256;
    height_ += stream.ReadByte();
    //宽度 占2字节 低位高位互换
    width_ = stream.ReadByte() * 256;
    width_ += stream.ReadByte();
    }
  • 相关阅读:
    Linux 下 Lua 与 LuaSQL 模块安装
    js学习笔记27----键盘事件
    js学习笔记26----事件冒泡,事件捕获
    js学习笔记25----Event对象
    js学习笔记24----焦点事件
    js学习笔记23----窗口尺寸及窗口事件
    js学习笔记22----BOM属性和方法
    VS Code 常用快捷键
    你不知道的JavaScript学习笔记1——作用域
    三种CSS方法实现loadingh点点点的效果
  • 原文地址:https://www.cnblogs.com/huizhang212/p/ImageJpg.html
Copyright © 2011-2022 走看看