以前解析图片真实大小都需要通过BitmapImage解析后才能看到,最近发现了一个方法,可以通过读取 Stream的方式来获取。
代码如下:
获取GIF图片的真实大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | private static Dictionary<string, int> GetGifWidthAndHeight(Stream stream) { Dictionary<string, int> imgSize = null; byte[] header = new byte[6]; stream.Read(header, 0, 6); int width = 0; int height = 0; if (!(header[0] == 0x47 && header[1] == 0x49 && header[2] == 0x46 && header[3] == 0x38 && (header[4] == 0x39 || header[4] == 0x37) && header[5] == 0x61)) { imgSize = null; } else { byte[] buffer = new byte[4]; stream.Read(buffer, 0, buffer.Length); width = BitConverter.ToInt16(buffer, 0); height = BitConverter.ToInt16(buffer, 2); imgSize = new Dictionary<string, int>(); imgSize.Add("width", width); imgSize.Add("height", height); } return imgSize; } |
获取PNG图片的真实大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | private static Dictionary<string, int> GetPngWidthAndHeight(Stream stream) { Dictionary<string, int> imgSize = null; int width = 0; int height = 0; byte[] header = new byte[8]; stream.Read(header, 0, 8); //Png图片 8字节:89 50 4E 47 0D 0A 1A 0A if (!(header[0] == 0x89 && header[1] == 0x50 && header[2] == 0x4E && header[3] == 0x47 && header[4] == 0x0D && header[5] == 0x0A && header[6] == 0x1A && header[7] == 0x0A)) { imgSize = null; } else { stream.Seek(8, SeekOrigin.Current); byte[] buffer = new byte[8]; stream.Read(buffer, 0, buffer.Length); Array.Reverse(buffer, 0, 4); Array.Reverse(buffer, 4, 4); width = BitConverter.ToInt32(buffer, 0); height = BitConverter.ToInt32(buffer, 4); imgSize = new Dictionary<string, int>(); imgSize.Add("width", width); imgSize.Add("height", height); } return imgSize; } |
获取JPG图片真实大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | private static Dictionary<string, int> GetJpgWidthAndHeight(Stream stream) { Dictionary<string, int> imgSize = null; //读取2个字节的SOI,即0xFFD8 byte[] header = new byte[2]; stream.Read(header, 0, 2); //判断是否为JPG,不是退出解析 if (!(header[0] == 0xFF && header[1] == 0xD8)) { //不是JPG图片 imgSize = null; } else { int type = -1; int ff = -1; //记录当前读取的位置 long ps = 0; //逐个遍历所以段,查找SOFO段 do { do { //每个新段的开始标识为oxff,查找下一个新段 ff = stream.ReadByte(); if (ff < 0) //文件结束 { return null; } } 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段,解析宽度和高度信息 imgSize = getJpgSize(stream); return imgSize; } default: //别的段都跳过 //获取段长度,直接跳过 ps = stream.ReadByte() * 256; ps = stream.Position + ps + stream.ReadByte() - 2; break; } if (ps + 1 >= stream.Length) //文件结束 { return imgSize; } stream.Position = ps; //移动指针 } while (type != 0xda); // 扫描行开始 } return imgSize; } |
注意:传入的Stream流的Positioin必须为0哦
惊了,猴子还有博客这种东西