PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Edge.Utilities/Imaging/ImageInfo.cs

#
C# | 616 lines | 321 code | 237 blank | 58 comment | 3 complexity | 4cc0d749969f033ea5fd7f9c7153261f MD5 | raw file
  1. namespace Edge.Utilities.Imaging
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.Drawing.Imaging;
  8. using System.IO;
  9. using System.Text;
  10. /// <summary>
  11. /// Specifies the data type of the values stored in the value data member of that same PropertyItem object.
  12. /// </summary>
  13. public enum PropertyTagType : short
  14. {
  15. /// <summary>Specifies that the format is 4 bits per pixel, indexed.</summary>
  16. PixelFormat4bppIndexed = 0,
  17. /// <summary>Specifies that the value data member is an array of bytes.</summary>
  18. Byte = 1,
  19. /// <summary>Specifies that the value data member is a null-terminated ASCII string. If you set the type data member of a PropertyItem object to PropertyTagTypeASCII, you should set the length data member to the length of the string including the NULL terminator. For example, the string HELLO would have a length of 6.</summary>
  20. ASCII = 2,
  21. /// <summary>Specifies that the value data member is an array of unsigned short (16-bit) integers.</summary>
  22. Int16 = 3,
  23. /// <summary>Specifies that the value data member is an array of unsigned long (32-bit) integers.</summary>
  24. Int32 = 4,
  25. /// <summary>Specifies that the value data member is an array of pairs of unsigned long integers. Each pair represents a fraction; the first integer is the numerator and the second integer is the denominator.</summary>
  26. Rational = 5,
  27. /// <summary>Specifies that the value data member is an array of bytes that can hold values of any data type.</summary>
  28. Undefined = 7,
  29. /// <summary>Specifies that the value data member is an array of signed long (32-bit) integers.</summary>
  30. SLONG = 9,
  31. /// <summary>Specifies that the value data member is an array of pairs of signed long integers. Each pair represents a fraction; the first integer is the numerator and the second integer is the denominator.</summary>
  32. SRational = 10
  33. }
  34. /// <summary>
  35. /// The following Enumeration gives list (and descriptions) of the property items supported in EXIF format.
  36. /// </summary>
  37. public enum PropertyTagId : int
  38. {
  39. Artist = 0x013B,
  40. BitsPerSample = 0x0102,
  41. CellHeight = 0x0109,
  42. CellWidth = 0x0108,
  43. ChrominanceTable = 0x5091,
  44. ColorMap = 0x0140,
  45. ColorTransferFunction = 0x501A,
  46. Compression = 0x0103,
  47. Copyright = 0x8298,
  48. DateTime = 0x0132,
  49. DocumentName = 0x010D,
  50. DotRange = 0x0150,
  51. Camera_Make = 0x010F,
  52. Camera_Model = 0x0110,
  53. ExifAperture = 0x9202,
  54. ExifBrightness = 0x9203,
  55. ExifCfaPattern = 0xA302,
  56. ExifColorSpace = 0xA001,
  57. ExifCompBPP = 0x9102,
  58. ExifCompConfig = 0x9101,
  59. ExifDTDigitized = 0x9004,
  60. ExifDTDigSS = 0x9292,
  61. ExifDTOrig = 0x9003,
  62. ExifDTOrigSS = 0x9291,
  63. ExifDTSubsec = 0x9290,
  64. ExifExposureBias = 0x9204,
  65. ExifExposureIndex = 0xA215,
  66. ExifExposureProg = 0x8822,
  67. ExifExposureTime = 0x829A,
  68. ExifFileSource = 0xA300,
  69. ExifFlash = 0x9209,
  70. ExifFlashEnergy = 0xA20B,
  71. ExifFNumber = 0x829D,
  72. ExifFocalLength = 0x920A,
  73. ExifFocalResUnit = 0xA210,
  74. ExifFocalXRes = 0xA20E,
  75. ExifFocalYRes = 0xA20F,
  76. ExifFPXVer = 0xA000,
  77. ExifIFD = 0x8769,
  78. ExifInterop = 0xA005,
  79. ExifISOSpeed = 0x8827,
  80. ExifLightSource = 0x9208,
  81. ExifMakerNote = 0x927C,
  82. ExifMaxAperture = 0x9205,
  83. ExifMeteringMode = 0x9207,
  84. ExifOECF = 0x8828,
  85. ExifPixXDim = 0xA002,
  86. ExifPixYDim = 0xA003,
  87. ExifRelatedWav = 0xA004,
  88. ExifSceneType = 0xA301,
  89. ExifSensingMethod = 0xA217,
  90. ExifShutterSpeed = 0x9201,
  91. ExifSpatialFR = 0xA20C,
  92. ExifSpectralSense = 0x8824,
  93. ExifSubjectDist = 0x9206,
  94. ExifSubjectLoc = 0xA214,
  95. ExifUserComment = 0x9286,
  96. ExifVer = 0x9000,
  97. ExtraSamples = 0x0152,
  98. FillOrder = 0x010A,
  99. FrameDelay = 0x5100,
  100. FreeByteCounts = 0x0121,
  101. FreeOffset = 0x0120,
  102. Gamma = 0x0301,
  103. GlobalPalette = 0x5102,
  104. GpsAltitude = 0x0006,
  105. GpsAltitudeRef = 0x0005,
  106. GpsDestBear = 0x0018,
  107. GpsDestBearRef = 0x0017,
  108. GpsDestDist = 0x001A,
  109. GpsDestDistRef = 0x0019,
  110. GpsDestLat = 0x0014,
  111. GpsDestLatRef = 0x0013,
  112. GpsDestLong = 0x0016,
  113. GpsDestLongRef = 0x0015,
  114. GpsGpsDop = 0x000B,
  115. GpsGpsMeasureMode = 0x000A,
  116. GpsGpsSatellites = 0x0008,
  117. GpsGpsStatus = 0x0009,
  118. GpsGpsTime = 0x0007,
  119. GpsIFD = 0x8825,
  120. GpsImgDir = 0x0011,
  121. GpsImgDirRef = 0x0010,
  122. GpsLatitude = 0x0002,
  123. GpsLatitudeRef = 0x0001,
  124. GpsLongitude = 0x0004,
  125. GpsLongitudeRef = 0x0003,
  126. GpsMapDatum = 0x0012,
  127. GpsSpeed = 0x000D,
  128. GpsSpeedRef = 0x000C,
  129. GpsTrack = 0x000F,
  130. GpsTrackRef = 0x000E,
  131. GpsVer = 0x0000,
  132. GrayResponseCurve = 0x0123,
  133. GrayResponseUnit = 0x0122,
  134. GridSize = 0x5011,
  135. HalftoneDegree = 0x500C,
  136. HalftoneHints = 0x0141,
  137. HalftoneLPI = 0x500A,
  138. HalftoneLPIUnit = 0x500B,
  139. HalftoneMisc = 0x500E,
  140. HalftoneScreen = 0x500F,
  141. HalftoneShape = 0x500D,
  142. HostComputer = 0x013C,
  143. ICCProfile = 0x8773,
  144. ICCProfileDescriptor = 0x0302,
  145. ImageDescription = 0x010E,
  146. ImageHeight = 0x0101,
  147. ImageTitle = 0x0320,
  148. ImageWidth = 0x0100,
  149. IndexBackground = 0x5103,
  150. IndexTransparent = 0x5104,
  151. InkNames = 0x014D,
  152. InkSet = 0x014C,
  153. JPEGACTables = 0x0209,
  154. JPEGDCTables = 0x0208,
  155. JPEGInterFormat = 0x0201,
  156. JPEGInterLength = 0x0202,
  157. JPEGLosslessPredictors = 0x0205,
  158. JPEGPointTransforms = 0x0206,
  159. JPEGProc = 0x0200,
  160. JPEGQTables = 0x0207,
  161. JPEGQuality = 0x5010,
  162. JPEGRestartInterval = 0x0203,
  163. LoopCount = 0x5101,
  164. LuminanceTable = 0x5090,
  165. MaxSampleValue = 0x0119,
  166. MinSampleValue = 0x0118,
  167. NewSubfileType = 0x00FE,
  168. NumberOfInks = 0x014E,
  169. Orientation = 0x0112,
  170. PageName = 0x011D,
  171. PageNumber = 0x0129,
  172. PaletteHistogram = 0x5113,
  173. PhotometricInterp = 0x0106,
  174. PixelPerUnitX = 0x5111,
  175. PixelPerUnitY = 0x5112,
  176. PixelUnit = 0x5110,
  177. PlanarConfig = 0x011C,
  178. Predictor = 0x013D,
  179. PrimaryChromaticities = 0x013F,
  180. PrintFlags = 0x5005,
  181. PrintFlagsBleedWidth = 0x5008,
  182. PrintFlagsBleedWidthScale = 0x5009,
  183. PrintFlagsCrop = 0x5007,
  184. PrintFlagsVersion = 0x5006,
  185. REFBlackWhite = 0x0214,
  186. ResolutionUnit = 0x0128,
  187. ResolutionXLengthUnit = 0x5003,
  188. ResolutionXUnit = 0x5001,
  189. ResolutionYLengthUnit = 0x5004,
  190. ResolutionYUnit = 0x5002,
  191. RowsPerStrip = 0x0116,
  192. SampleFormat = 0x0153,
  193. SamplesPerPixel = 0x0115,
  194. SMaxSampleValue = 0x0155,
  195. SMinSampleValue = 0x0154,
  196. SoftwareUsed = 0x0131,
  197. SRGBRenderingIntent = 0x0303,
  198. StripBytesCount = 0x0117,
  199. StripOffsets = 0x0111,
  200. SubfileType = 0x00FF,
  201. T4Option = 0x0124,
  202. T6Option = 0x0125,
  203. TargetPrinter = 0x0151,
  204. ThreshHolding = 0x0107,
  205. ThumbnailArtist = 0x5034,
  206. ThumbnailBitsPerSample = 0x5022,
  207. ThumbnailColorDepth = 0x5015,
  208. ThumbnailCompressedSize = 0x5019,
  209. ThumbnailCompression = 0x5023,
  210. ThumbnailCopyRight = 0x503B,
  211. ThumbnailData = 0x501B,
  212. ThumbnailDateTime = 0x5033,
  213. ThumbnailEquipMake = 0x5026,
  214. ThumbnailEquipModel = 0x5027,
  215. ThumbnailFormat = 0x5012,
  216. ThumbnailHeight = 0x5014,
  217. ThumbnailImageDescription = 0x5025,
  218. ThumbnailImageHeight = 0x5021,
  219. ThumbnailImageWidth = 0x5020,
  220. ThumbnailOrientation = 0x5029,
  221. ThumbnailPhotometricInterp = 0x5024,
  222. ThumbnailPlanarConfig = 0x502F,
  223. ThumbnailPlanes = 0x5016,
  224. ThumbnailPrimaryChromaticities = 0x5036,
  225. ThumbnailRawBytes = 0x5017,
  226. ThumbnailRefBlackWhite = 0x503A,
  227. ThumbnailResolutionUnit = 0x5030,
  228. ThumbnailResolutionX = 0x502D,
  229. ThumbnailResolutionY = 0x502E,
  230. ThumbnailRowsPerStrip = 0x502B,
  231. ThumbnailSamplesPerPixel = 0x502A,
  232. ThumbnailSize = 0x5018,
  233. ThumbnailSoftwareUsed = 0x5032,
  234. ThumbnailStripBytesCount = 0x502C,
  235. ThumbnailStripOffsets = 0x5028,
  236. ThumbnailTransferFunction = 0x5031,
  237. ThumbnailWhitePoint = 0x5035,
  238. ThumbnailWidth = 0x5013,
  239. ThumbnailYCbCrCoefficients = 0x5037,
  240. ThumbnailYCbCrPositioning = 0x5039,
  241. ThumbnailYCbCrSubsampling = 0x5038,
  242. TileByteCounts = 0x0145,
  243. TileLength = 0x0143,
  244. TileOffset = 0x0144,
  245. TileWidth = 0x0142,
  246. TransferFunction = 0x012D,
  247. TransferRange = 0x0156,
  248. WhitePoint = 0x013E,
  249. XPosition = 0x011E,
  250. XResolution = 0x011A,
  251. YCbCrCoefficients = 0x0211,
  252. YCbCrPositioning = 0x0213,
  253. YCbCrSubsampling = 0x0212,
  254. YPosition = 0x011F,
  255. YResolution = 0x011B
  256. }
  257. /// <summary>
  258. /// Retrieves information about an image
  259. /// </summary>
  260. /// <example>
  261. /// <code language="c#">
  262. /// Image image = Image.FromFile(path);
  263. /// ImageInfo info = new ImageInfo(image);
  264. /// foreach (KeyValuePair<PropertyTagId, KeyValuePair<PropertyTagType, Object>>property in info.ImageProps)
  265. /// {
  266. /// string parsed = property.Value.ToString();
  267. /// parsed = parsed.Replace("[", "");
  268. /// parsed = parsed.Replace("]", "");
  269. /// string[] tokens = parsed.Split(',');
  270. /// string value = tokens[1].Trim();
  271. /// if (value != "Undefined Data" && value != "System.Object")
  272. /// {
  273. /// Console.WriteLine(property.Key.ToString() + ": " + value);
  274. /// }
  275. /// }
  276. /// </code>
  277. /// </example>
  278. public class ImageInfo
  279. {
  280. /// <summary>
  281. /// Stores image properties.
  282. /// </summary>
  283. private Dictionary<PropertyTagId, KeyValuePair<PropertyTagType, object>> imageProps =
  284. new Dictionary<PropertyTagId, KeyValuePair<PropertyTagType, object>>();
  285. /// <summary>
  286. /// Internally stores the image to inspect.
  287. /// </summary>
  288. private Image image;
  289. /// <summary>
  290. /// Initializes a new instance of the ImageInfo class.
  291. /// </summary>
  292. /// <param name="newImage">Image to inspect.</param>
  293. public ImageInfo(Image newImage)
  294. {
  295. this.image = newImage;
  296. this.BuildPropsHash();
  297. }
  298. /// <summary>
  299. /// Gets or sets image properties.
  300. /// </summary>
  301. public Dictionary<PropertyTagId, KeyValuePair<PropertyTagType, object>> ImageProps
  302. {
  303. get { return this.imageProps; }
  304. set { this.imageProps = value; }
  305. }
  306. /// <summary>
  307. /// Converts a number into an enumerable object.
  308. /// </summary>
  309. /// <typeparam name="T">Type to convert to.</typeparam>
  310. /// <param name="number">Number to convert.</param>
  311. /// <returns>Enumberable object.</returns>
  312. public T NumToEnum<T>(int number)
  313. {
  314. return (T)Enum.ToObject(typeof(T), number);
  315. }
  316. /// <summary>
  317. /// Builds the hash of image properties.
  318. /// </summary>
  319. private void BuildPropsHash()
  320. {
  321. foreach (PropertyItem property in this.image.PropertyItems)
  322. {
  323. object propValue = new object();
  324. switch ((PropertyTagType)property.Type)
  325. {
  326. case PropertyTagType.ASCII:
  327. ASCIIEncoding encoding = new ASCIIEncoding();
  328. propValue = encoding.GetString(
  329. property.Value, 0, property.Len - 1);
  330. break;
  331. case PropertyTagType.Int16:
  332. propValue = BitConverter.ToInt16(
  333. property.Value, 0);
  334. break;
  335. case PropertyTagType.SLONG:
  336. case PropertyTagType.Int32:
  337. propValue = BitConverter.ToInt32(
  338. property.Value, 0);
  339. break;
  340. case PropertyTagType.SRational:
  341. case PropertyTagType.Rational:
  342. uint numberator =
  343. BitConverter.ToUInt32(
  344. property.Value, 0);
  345. uint denominator =
  346. BitConverter.ToUInt32(
  347. property.Value, 4);
  348. try
  349. {
  350. propValue = ((double)numberator
  351. / (double)denominator).ToString();
  352. if (propValue.ToString() == "NaN")
  353. {
  354. propValue = "0";
  355. }
  356. }
  357. catch (DivideByZeroException)
  358. {
  359. propValue = "0";
  360. }
  361. break;
  362. case PropertyTagType.Undefined:
  363. propValue = "Undefined Data";
  364. break;
  365. }
  366. try
  367. {
  368. this.ImageProps.Add(
  369. NumToEnum<PropertyTagId>(property.Id),
  370. new KeyValuePair<PropertyTagType, object>(NumToEnum<PropertyTagType>(property.Type), propValue));
  371. }
  372. catch (Exception)
  373. {
  374. continue;
  375. }
  376. }
  377. }
  378. }
  379. }