Windows Phone 解析圖片格式

l_serein發表於2012-11-29

在Windows Phone中用於顯示圖片的是Image控制元件,不過Image控制元件目前只支援兩種格式的圖片,即Png和Jpg。平時我們經常用的圖片還有Gif和Bmp兩種,對於這兩種圖片我們無法通過Image來顯示。需要用第三方開發的控制元件來顯示,ImageTools是開源社群CodePlex提供的,可以通過http://imagetools.codeplex.com/下載DLL以及原始碼,通過ImageTools我們可以顯示Gif和Bmp圖片。
  因此對於比較常用的圖片格式Png、Jpg、Gif、Bmp,我們需要針對不同的圖片格式使用不同的控制元件來顯示,這裡就有一個來解析圖片格式的問題。我們不能單純的用檔案字尾名.png、.jpg、.jpeg、.gif、.bmp來區分圖片格式,因為實際上我們可以直接修改圖片字尾名,修改字尾名並不能修改圖片的格式,圖片還是保持它原來的格式。
  圖片檔案的格式結果中,在頭部資訊(一般都會在圖片檔案最開始的幾個位元組)中都會包含圖片的格式資訊。下面就列車常用的這幾種格式圖片的頭部資訊標識(十六進位制)。
  1.Png圖片檔案包括8位元組:89 50 4E 47 0D 0A 1A 0A。即為 .PNG....。
  2.Jpg圖片檔案包括2位元組:FF D8。
  3.Gif圖片檔案包括6位元組:47 49 46 38 39|37 61 。即為 GIF89(7)a。
  4.Bmp圖片檔案包括2位元組:42 4D。即為 BM。
  根據圖片問題頭標識資訊我們可以能很方便的判斷出檔案的格式,首先我們需要獲取圖片檔案的位元組流資訊,程式碼如下。
  View Code
        //獲取圖片檔案流,根據圖片是資原始檔或者獨立儲存檔案分別處理
        Stream stream = null;
        //如果是資原始檔處理
        StreamResourceInfo info = Application.GetResourceStream(new Uri(path, UriKind.Relative));
        if (info != null)
        {
            stream = info.Stream;
        }
        //如果是獨立儲存檔案處理
        using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
        {
            //開啟檔案
            stream = myIsolatedStorage.OpenFile(path, FileMode.Open, FileAccess.Read);
        }

  從圖片檔案流stream中讀取8個位元組,然後再根據不同的圖片格式做檔案頭匹配比較具能判斷出檔案的格式,程式碼如下。
  View Code
        /// <summary>
        /// 定義圖片格式
        /// </summary>
        public enum ImageType
        {
            Null,
            Png,
            Jpg,
            Gif,
            Bmp
        }

        /// <summary>
        /// 獲取圖片格式
        /// </summary>
        private ImageType getImageType(Stream stream)
        {
            //圖片格式
            ImageType type = ImageType.Null;

            //讀取圖片檔案頭8個位元組,並根據若干個位元組來確定圖片格式
            byte[] header = new byte[8];
            stream.Read(header, 0, 8);

            //確定圖片格式
            if (header[0] == 0x89 &&
                header[1] == 0x50 && // P
                header[2] == 0x4E && // N
                header[3] == 0x47 && // G
                header[4] == 0x0D &&
                header[5] == 0x0A &&
                header[6] == 0x1A &&
                header[7] == 0x0A)
            {
                //Png圖片 8位元組:89 50 4E 47 0D 0A 1A 0A
                type = ImageType.Png;
            }
            else if (header[0] == 0xFF &&
                    header[1] == 0xD8)
            {
                //Jpg圖片 2位元組:FF D8
                type = ImageType.Jpg;
            }
            else if (header[0] == 0x47 &&   // G
                    header[1] == 0x49 &&    // I
                    header[2] == 0x46 &&    // F
                    header[3] == 0x38 &&    // 8
                    (header[4] == 0x39 ||   // 9
                    header[4] == 0x37) &&   // 7
                    header[5] == 0x61)      // a
            {
                //Gif圖片 6位元組:47 49 46 38 39|37 61
                type = ImageType.Gif;
            }
            else if (header[0] == 0x42 &&   //B
                    header[1] == 0x4D)      //M
            {
                //Bmp圖片 2位元組:42 4D
                type = ImageType.Bmp;
            }

            //關閉位元組流
            stream.Close();

            return type;
        }

  解析到圖片格式後,我們就可以根據圖片格式選擇對應的控制元件來顯示圖片了。

相關文章