直接上代码,很好理解~~~
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 }