Windows Phone 解析圖片尺寸之jpg

來源:互聯網
上載者:User

  上一篇介紹了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();
}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.