C# 中读取图片头判断图片宽高

直接上代码,很好理解~~~ 

  1 public static class ImageHeader
  2         {
  3             const string errorMessage = "Could not recognise image format.";
  4 
  5             private static Dictionary<byte[], Func<BinaryReader, Size>> imageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, Size>>()
  6             { 
  7                 { new byte[] { 0x42, 0x4D }, DecodeBitmap }, 
  8                 { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif }, 
  9                 { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif }, 
 10                 { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng },
 11                 { new byte[] { 0xff, 0xd8 }, DecodeJfif }, 
 12             };
 13 
 14             /// <summary>        
 15             /// Gets the dimensions of an image.        
 16             /// </summary>        
 17             /// <param name="path">The path of the image to get the dimensions of.</param>        
 18             /// <returns>The dimensions of the specified image.</returns>        
 19             /// <exception cref="ArgumentException">The image was of an unrecognised format.</exception>        
 20             public static Size GetDimensions(string path)
 21             {
 22                 try
 23                 {
 24                     using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)))
 25                     {
 26                         try
 27                         {
 28                             return GetDimensions(binaryReader);
 29                         }
 30                         catch (ArgumentException e)
 31                         {
 32                             string newMessage = string.Format("{0} file: '{1}' ", errorMessage, path);
 33 
 34                             throw new ArgumentException(newMessage, "path", e);
 35                         }
 36                     }
 37                 }
 38                 catch (ArgumentException)
 39                 {
 40                     using (Bitmap b = new Bitmap(path))
 41                     {
 42                         return b.Size;
 43                     }
 44                 }
 45             }
 46 
 47             /// <summary>        
 48             /// Gets the dimensions of an image.        
 49             /// </summary>        
 50             /// <param name="path">The path of the image to get the dimensions of.</param>        
 51             /// <returns>The dimensions of the specified image.</returns>        
 52             /// <exception cref="ArgumentException">The image was of an unrecognised format.</exception>            
 53             public static Size GetDimensions(BinaryReader binaryReader)
 54             {
 55                 int maxMagicBytesLength = imageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length;
 56                 byte[] magicBytes = new byte[maxMagicBytesLength];
 57                 for (int i = 0; i < maxMagicBytesLength; i += 1)
 58                 {
 59                     magicBytes[i] = binaryReader.ReadByte();
 60                     foreach (var kvPair in imageFormatDecoders)
 61                     {
 62                         if (StartsWith(magicBytes, kvPair.Key))
 63                         {
 64                             return kvPair.Value(binaryReader);
 65                         }
 66                     }
 67                 }
 68 
 69                 throw new ArgumentException(errorMessage, "binaryReader");
 70             }
 71 
 72             private static bool StartsWith(byte[] thisBytes, byte[] thatBytes)
 73             {
 74                 for (int i = 0; i < thatBytes.Length; i += 1)
 75                 {
 76                     if (thisBytes[i] != thatBytes[i])
 77                     {
 78                         return false;
 79                     }
 80                 }
 81 
 82                 return true;
 83             }
 84 
 85             private static short ReadLittleEndianInt16(BinaryReader binaryReader)
 86             {
 87                 byte[] bytes = new byte[sizeof(short)];
 88 
 89                 for (int i = 0; i < sizeof(short); i += 1)
 90                 {
 91                     bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte();
 92                 }
 93                 return BitConverter.ToInt16(bytes, 0);
 94             }
 95 
 96             private static ushort ReadLittleEndianUInt16(BinaryReader binaryReader)
 97             {
 98                 byte[] bytes = new byte[sizeof(ushort)];
 99 
100                 for (int i = 0; i < sizeof(ushort); i += 1)
101                 {
102                     bytes[sizeof(ushort) - 1 - i] = binaryReader.ReadByte();
103                 }
104                 return BitConverter.ToUInt16(bytes, 0);
105             }
106 
107             private static int ReadLittleEndianInt32(BinaryReader binaryReader)
108             {
109                 byte[] bytes = new byte[sizeof(int)];
110                 for (int i = 0; i < sizeof(int); i += 1)
111                 {
112                     bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte();
113                 }
114                 return BitConverter.ToInt32(bytes, 0);
115             }
116 
117             private static Size DecodeBitmap(BinaryReader binaryReader)
118             {
119                 binaryReader.ReadBytes(16);
120                 int width = binaryReader.ReadInt32();
121                 int height = binaryReader.ReadInt32();
122                 return new Size(width, height);
123             }
124 
125             private static Size DecodeGif(BinaryReader binaryReader)
126             {
127                 int width = binaryReader.ReadInt16();
128                 int height = binaryReader.ReadInt16();
129                 return new Size(width, height);
130             }
131 
132             private static Size DecodePng(BinaryReader binaryReader)
133             {
134                 binaryReader.ReadBytes(8);
135                 int width = ReadLittleEndianInt32(binaryReader);
136                 int height = ReadLittleEndianInt32(binaryReader);
137                 return new Size(width, height);
138             }
139 
140             private static Size DecodeJfif(BinaryReader binaryReader)
141             {
142                 while (binaryReader.ReadByte() == 0xff)
143                 {
144                     byte marker = binaryReader.ReadByte();
145                     short chunkLength = ReadLittleEndianInt16(binaryReader);
146                     if (marker == 0xc0)
147                     {
148                         binaryReader.ReadByte();
149                         int height = ReadLittleEndianInt16(binaryReader);
150                         int width = ReadLittleEndianInt16(binaryReader);
151                         return new Size(width, height);
152                     }
153 
154                     if (chunkLength < 0)
155                     {
156                         ushort uchunkLength = (ushort)chunkLength;
157                         binaryReader.ReadBytes(uchunkLength - 2);
158                     }
159                     else
160                     {
161                         binaryReader.ReadBytes(chunkLength - 2);
162                     }
163                 }
164 
165                 throw new ArgumentException(errorMessage);
166             }
167         }

 

posted @ 2012-11-19 13:06  路漫漫其修远兮~~~  阅读(2444)  评论(4编辑  收藏  举报