栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在不读取整个文件的情况下获取图像尺寸

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在不读取整个文件的情况下获取图像尺寸

与往常一样,最好的选择是找到一个经过良好测试的库。但是,您说这很困难,因此下面是一些在很大程度上未经测试的狡猾代码,它们在相当多的情况下都适用:

using System;using System.Collections.Generic;using System.Drawing;using System.IO;using System.Linq;namespace ImageDimensions{    public static class ImageHelper    {        const string errorMessage = "Could not recognize image format.";        private static Dictionary<byte[], Func<BinaryReader, Size>> imageFormatDeprers = new Dictionary<byte[], Func<BinaryReader, Size>>()        { { new byte[]{ 0x42, 0x4D }, DepreBitmap}, { new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DepreGif }, { new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DepreGif }, { new byte[]{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DeprePng }, { new byte[]{ 0xff, 0xd8 }, DepreJfif },        };        /// <summary>        /// Gets the dimensions of an image.        /// </summary>        /// <param name="path">The path of the image to get the dimensions of.</param>        /// <returns>The dimensions of the specified image.</returns>        /// <exception cref="ArgumentException">The image was of an unrecognized format.</exception>        public static Size GetDimensions(string path)        { using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path))) {     try     {         return GetDimensions(binaryReader);     }     catch (ArgumentException e)     {         if (e.Message.StartsWith(errorMessage))         {  throw new ArgumentException(errorMessage, "path", e);         }         else         {  throw e;         }     } }        }        /// <summary>        /// Gets the dimensions of an image.        /// </summary>        /// <param name="path">The path of the image to get the dimensions of.</param>        /// <returns>The dimensions of the specified image.</returns>        /// <exception cref="ArgumentException">The image was of an unrecognized format.</exception> public static Size GetDimensions(BinaryReader binaryReader)        { int maxMagicBytesLength = imageFormatDeprers.Keys.OrderByDescending(x => x.Length).First().Length; byte[] magicBytes = new byte[maxMagicBytesLength]; for (int i = 0; i < maxMagicBytesLength; i += 1) {     magicBytes[i] = binaryReader.ReadByte();     foreach(var kvPair in imageFormatDeprers)     {         if (magicBytes.StartsWith(kvPair.Key))         {  return kvPair.Value(binaryReader);         }     } } throw new ArgumentException(errorMessage, "binaryReader");        }        private static bool StartsWith(this byte[] thisBytes, byte[] thatBytes)        { for(int i = 0; i < thatBytes.Length; i+= 1) {     if (thisBytes[i] != thatBytes[i])     {         return false;     } } return true;        }        private static short ReadLittleEndianInt16(this BinaryReader binaryReader)        { byte[] bytes = new byte[sizeof(short)]; for (int i = 0; i < sizeof(short); i += 1) {     bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte(); } return BitConverter.ToInt16(bytes, 0);        }        private static int ReadLittleEndianInt32(this BinaryReader binaryReader)        { byte[] bytes = new byte[sizeof(int)]; for (int i = 0; i < sizeof(int); i += 1) {     bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte(); } return BitConverter.ToInt32(bytes, 0);        }        private static Size DepreBitmap(BinaryReader binaryReader)        { binaryReader.ReadBytes(16); int width = binaryReader.ReadInt32(); int height = binaryReader.ReadInt32(); return new Size(width, height);        }        private static Size DepreGif(BinaryReader binaryReader)        { int width = binaryReader.ReadInt16(); int height = binaryReader.ReadInt16(); return new Size(width, height);        }        private static Size DeprePng(BinaryReader binaryReader)        { binaryReader.ReadBytes(8); int width = binaryReader.ReadLittleEndianInt32(); int height = binaryReader.ReadLittleEndianInt32(); return new Size(width, height);        }        private static Size DepreJfif(BinaryReader binaryReader)        { while (binaryReader.ReadByte() == 0xff) {     byte marker = binaryReader.ReadByte();     short chunkLength = binaryReader.ReadLittleEndianInt16();     if (marker == 0xc0)     {         binaryReader.ReadByte();         int height = binaryReader.ReadLittleEndianInt16();         int width = binaryReader.ReadLittleEndianInt16();         return new Size(width, height);     }     binaryReader.ReadBytes(chunkLength - 2); } throw new ArgumentException(errorMessage);        }    }}

希望代码相当明显。要添加新的文件格式,可以将其添加到

imageFormatDeprers
其中,其键是“魔术位”数组,该数组出现在给定格式的每个文件的开头,而值是一个从流中提取大小的函数。大多数格式都足够简单,唯一真正的臭味是jpeg。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/416869.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号