久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

常見圖片寬高解析

 勤奮不止 2021-01-02

于比較常用的圖片格式Png,、Jpg、Gif,、Bmp,我們需要針對不同的圖片格式使用不同的控件來顯示,,這里就有一個來解析圖片格式的問題,。我們不能單純的用文件后綴名.png、.jpg,、.jpeg,、.gif、.bmp來區(qū)分圖片格式,,因為實際上我們可以直接修改圖片后綴名,,修改后綴名并不能修改圖片的格式,圖片還是保持它原來的格式,。

圖片文件的格式結果中,,在頭部信息(一般都會在圖片文件最開始的幾個字節(jié))中都會包含圖片的格式信息。下面就列車常用的這幾種格式圖片的頭部信息標識(十六進制),。

1.Png圖片文件包括8字節(jié):89 50 4E 47 0D 0A 1A 0A,。即為 .PNG....。 

2.Jpg圖片文件包括2字節(jié):FF D8,。

3.Gif圖片文件包括6字節(jié):47 49 46 38 39|37 61 ,。即為 GIF89(7)a。

4.Bmp圖片文件包括2字節(jié):42 4D,。即為 BM,。

根據(jù)圖片問題頭標識信息我們可以能很方便的判斷出文件的格式,首先我們需要獲取圖片文件的字節(jié)流信息,,代碼如下,。

復制代碼

Stream stream = ;                 StreamResourceInfo info = Application.GetResourceStream( Uri(path, UriKind.Relative));          (info != )         {             stream = info.Stream;         }                  (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())         {                         stream = myIsolatedStorage.OpenFile(path, FileMode.Open, FileAccess.Read);         }

復制代碼

從圖片文件流stream中讀取8個字節(jié),然后再根據(jù)不同的圖片格式做文件頭匹配比較具能判斷出文件的格式,,代碼如下,。

復制代碼

ImageType         {             Null,             Png,             Jpg,             Gif,             Bmp         }                    ImageType getImageType(Stream stream)         {                         ImageType type = ImageType.Null;                         [] header =  [];             stream.Read(header, , );                          (header[] ==  &&                 header[] ==  &&                 header[] ==  &&                 header[] ==  &&                 header[] ==  &&                 header[] ==  &&                 header[] ==  &&                 header[] == )             {                                 type = ImageType.Png;             }               (header[] ==  &&                     header[] == )             {                                 type = ImageType.Jpg;             }               (header[] ==  &&                       header[] ==  &&                        header[] ==  &&                        header[] ==  &&                        (header[] ==  ||                       header[] == ) &&                       header[] == )                  {                                 type = ImageType.Gif;             }               (header[] ==  &&                       header[] == )                  {                                 type = ImageType.Bmp;             }                         stream.Close();              type;         }

復制代碼

解析到圖片格式后,我們就可以根據(jù)圖片格式選擇對應的控件來顯示圖片了,。

PNG:

要解析Png圖片的寬度和高度信息,,首先需要了解Png圖片的數(shù)據(jù)塊結構,Png圖片的尺寸信息存放在文件頭數(shù)據(jù)塊中,所以我們需要了解文件頭的數(shù)據(jù)塊結構,。

文件頭數(shù)據(jù)塊IHDR(header chunk):它包含有PNG文件中存儲的圖像數(shù)據(jù)的基本信息,,并要作為第一個數(shù)據(jù)塊出現(xiàn)在PNG數(shù)據(jù)流中,而且一個PNG數(shù)據(jù)流中只能有一個文件頭數(shù)據(jù)塊,。 文件頭數(shù)據(jù)塊由13字節(jié)組成,,其中前8個字節(jié)即為圖片的寬度和高度信息,各占4個字節(jié),。

文件頭數(shù)據(jù)塊是第一個數(shù)據(jù)塊,,但是在數(shù)據(jù)塊前,也就是PNG圖片文件的最開始位置首先存儲的是PNG文件署名域,,占8個字節(jié),,即:89 50 4e 47 0d 0a 1a 0a ( .PNG....),通過這個可以判斷圖片是否為PNG格式,,接下來是文件頭數(shù)據(jù)塊的長度和標識,,各占4個字節(jié),文件頭數(shù)據(jù)塊的長度為13,,所以文件頭數(shù)據(jù)塊的長度固定為 00 00 00 0D,,而文件頭數(shù)據(jù)塊的標識為49 48 44 52,即“IHDR”,。

通過上面的解析,,我們可以分一下幾步來解析PNG圖片的寬度和高度。

1.首先讀取起始位的8個字節(jié),,即PNG文件署名域,,判斷圖片是否為PNG格式,如果不是,,則退出,。

復制代碼

[] header =  [];         stream.Read(header, , );                  (!(header[] ==  &&             header[] ==  &&             header[] ==  &&             header[] ==  &&             header[] ==  &&             header[] ==  &&             header[] ==  &&             header[] == ))         {                         ;         }

復制代碼

2.然后跳過8個字節(jié),即文件頭數(shù)據(jù)塊的長度值 00 00 00 0D,,以及文件頭數(shù)據(jù)塊標識 49 48 44 52(IHDR)。

stream.Seek(, SeekOrigin.Current);

3.接下來要讀取就是圖片的寬度和高度值,,讀取8個字節(jié),,由于是按照高低位調換存儲,所以需要做高低位轉換,,轉換后通過BitConverter類直接將字節(jié)類型轉換為整數(shù)型即為圖片的尺寸,。

復制代碼

[] buffer =  [];         stream.Read(buffer, , buffer.Length);         Array.Reverse(buffer, , );         Array.Reverse(buffer, , );         width_ = BitConverter.ToInt32(buffer, );         height_ = BitConverter.ToInt32(buffer, );

復制代碼

GIF:

GIF圖片的文件格式相對比較簡單,其中寬度和高度信息存放在邏輯視屏描述塊的前4個字節(jié),,而邏輯視屏描述塊是GIF圖片的第二塊區(qū)域,,第一個區(qū)域為6個字節(jié)的頭部,頭部包括標識符和版本。下表列出到高度信息為止的各個字節(jié)的描述,。

名稱

字節(jié)

說明

頭部

標識符

3

GIF  47 49 46

版本

3

87a(89a) 38 39|37 61

邏輯視屏描述塊

寬度

2

高度

2

根據(jù)上面的格式很容易獲取圖片的高度和寬度信息,,具體代碼如下。

復制代碼

[] header =  [];         stream.Read(header, , );          (!(header[] ==  &&                       header[] ==  &&                    header[] ==  &&                    header[] ==  &&                    (header[] ==  ||                   header[] == ) &&                   header[] == ))             {                         ;         }                 [] buffer =  [];         stream.Read(buffer, , buffer.Length);         width_ = BitConverter.ToInt16(buffer, );         height_ = BitConverter.ToInt16(buffer, );

復制代碼

BMP:

典型的位圖文件格式通常包含下面幾個數(shù)據(jù)塊:

位圖頭:保存位圖文件的總體信息,。

位圖信息:保存位圖圖像的詳細信息,。

調色板:保存所用顏色的定義。

位圖數(shù)據(jù):保存一個又一個像素的實際圖像,。

通過解析位圖頭我們可以判斷圖片是否為bmp格式,,而我們所需要的圖片尺寸信息存儲在位圖信息數(shù)據(jù)塊里。所以我們需要詳細了解位圖頭和位圖信息兩個數(shù)據(jù)塊的存儲結構,。

位圖頭,,這部分是識別信息,典型的應用程序會首先普通讀取這部分數(shù)據(jù)以確保的確是位圖文件并且沒有損壞,。

字節(jié) #0-1 保存位圖文件的標識符,,這兩個字節(jié)的典型數(shù)據(jù)是BM。

字節(jié) #2-5 使用一個dword保存位圖文件大小,。

字節(jié) #6-9 是保留部分,,留做以后的擴展使用,對實際的解碼格式?jīng)]有影響。

字節(jié) #10-13 保存位圖數(shù)據(jù)位置的地址偏移,,也就是起始地址,。

位圖信息,這部分告訴應用程序圖像的詳細信息,,在屏幕上顯示圖像將會使用這些信息,,它從文件的第15個字節(jié)開始。

字節(jié) #14-17 定義以下用來描述影像的區(qū)塊(BitmapInfoHeader)的大小,。它的值是:40 - Windows 3.2,、95、NT,、12 - OS/2 1.x,、240 - OS/2 2.x

字節(jié) #18-21 保存位圖寬度(以像素個數(shù)表示)。

字節(jié) #22-25 保存位圖高度(以像素個數(shù)表示),。

…………

以上關于bmp文件結構的內容參考維基百科http://zh./wiki/BMP,。

通過上面對BMP圖片格式的了解,可以用下面的代碼來解析bmp圖片的尺寸大小,。

復制代碼

[] header =  [];         stream.Read(header, , );          ( !(header[] ==  && header[] == ))         {                         ;         }                 stream.Seek(, SeekOrigin.Current);                 [] buffer =  [];         stream.Read(buffer, , buffer.Length);         width_ = BitConverter.ToInt32(buffer, );         height_ = BitConverter.ToInt32(buffer, );

復制代碼

JPG:

由于jpg圖片的格式相對于png要復雜很多,,所以首先我們要先清楚的了解jpg圖片的數(shù)據(jù)格式,jpg圖片包括SOI和數(shù)據(jù)兩個部分,。

SOI,,Start of Image,圖像開始,標記代碼 2字節(jié) 固定值0xFFD8,。

數(shù)據(jù)部分分成很多數(shù)據(jù)段,,數(shù)據(jù)段的一般結構如下。

段數(shù)據(jù)結構

名稱

字節(jié)

說明

段標識

>= 1

多于一個的0xFF

段類型

1

類型編碼(稱作“標記碼”)

段長度

2

包括段內容和段長度本身,不包括段標識和段類型

短內容

<= 65533

段類型有30種,,但只有10種是必須被所有程序識別的,,其它的類型都可以忽略。在這么多的段中,,其中JPG圖片的尺寸相關信息存儲在SOF0(圖像基本信息)段中,。所以需要詳細了解一下SOFO段的數(shù)據(jù)結構。

SOFO段結構

名稱

字節(jié)

說明

段標識

1

0XFF

段類型

1

0XCO JFIF格式的為0XC2

段長度

2

其值=8+組件數(shù)量×3

樣本精度

1

8 每個樣本位數(shù)(大多數(shù)軟件不支持12和16)

圖片高的

2

采用Motorola格式,,即:高位在前,,低位在后

圖片寬度

2

采用Motorola格式,即:高位在前,,低位在后

由于我們是為了解析JPG圖片的寬度和高度信息,,所以上表SOFO段結構只列出了到寬度為止結構信息,接下來還有其他一些圖片的相關信息,,這里就不再列出,。

根據(jù)上面對JPG圖片格式的解析,我們可以分一下幾步來解析JPG圖片的尺寸信息,。

1.讀取2個字節(jié)的SOI,,即0xFFD8,根據(jù)這兩個字節(jié)判斷圖片是否為JPG圖片,,如果不是,,則退出解析過程。

復制代碼

[] header =  [];         stream.Read(header, , );                  (!(header[] ==  &&             header[] == ))         {                         ;         }

復制代碼

2.接下來就需要解析圖片的數(shù)據(jù)部分,,由于數(shù)據(jù)部分是有很多不同的數(shù)據(jù)段構成,,數(shù)據(jù)段擁有一些共同的特性,所以這里我們需要做一個循環(huán)來逐個遍歷查找到SOFO數(shù)據(jù)段,。

復制代碼

type = -;          ff = -;                  ps = ;                          {                          {                                 ff = stream.ReadByte();                  (ff < )                 {                     ;                 }             }  (ff != );                          {                                 type = stream.ReadByte();             }  (type == );                         ps = stream.Position;              (type)             {                  :                  :                  :                  :                  :                  :                  :                  :                  :                  :                     ;                  :                  :                     {                                                 getJpgSize(stream);                         ;                     }                 :                     ps = stream.ReadByte() * ;                     ps = stream.Position + ps + stream.ReadByte() - ;                     ;             }              (ps +  >= stream.Length)             {                 ;             }             stream.Position = ps;         }  (type != );

復制代碼

3.找到SOFO數(shù)據(jù)段后,,就可以解析圖片的寬度和高度信息。

復制代碼

getJpgSize(Stream stream)         {                         stream.Seek(, SeekOrigin.Current);                         height_ = stream.ReadByte() * ;             height_ += stream.ReadByte();                         width_ = stream.ReadByte() * ;             width_ += stream.ReadByte();         }

復制代碼

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多