public GPSRational(byte[] bytes) { byte[] h = new byte[8]; byte[] m = new byte[8]; byte[] s = new byte[8]; Array.Copy(bytes, 0, h, 0, 8); Array.Copy(bytes, 8, m, 0, 8); Array.Copy(bytes, 16, s, 0, 8); _hours = new Rational(h); _minutes = new Rational(m); _seconds = new Rational(s); }
private static string ReadTag(Image image, int propId) { string value = string.Empty; PropertyItem pitem; try { pitem = image.GetPropertyItem(propId); } catch (Exception ex) { throw ex; } switch (pitem.Type) { case 0x1: if (pitem.Value.Length == 4) { value = "Version " + pitem.Value[0].ToString() + "." + pitem.Value[1].ToString(); } else if (pitem.Id == 0x5 && pitem.Value[0] == 0) { value = "Sea level"; } else { value = pitem.Value[0].ToString(); } break; case 0x2: value = Ascii.GetString(pitem.Value).Trim('\0'); if (pitem.Id == 0x1 || pitem.Id == 0x13) { if (value == "N") { value = "North latitude"; } else if (value == "S") { value = "South latitude"; } else { value = "reserved"; } } if (pitem.Id == 0x3 || pitem.Id == 0x15) { if (value == "E") { value = "East longitude"; } else if (value == "W") { value = "West longitude"; } else { value = "reserved"; } } if (pitem.Id == 0x9) { if (value == "A") { value = "Measurement in progress"; } else if (value == "V") { value = "Measurement Interoperability"; } else { value = "reserved"; } } if (pitem.Id == 0xA) { if (value == "2") { value = "2-dimensional measurement"; } else if (value == "3") { value = "3-dimensional measurement"; } else { value = "reserved"; } } if (pitem.Id == 0xC || pitem.Id == 0x19) { if (value == "K") { value = "Kilometers per hour"; } else if (value == "M") { value = "Miles per hour"; } else if (value == "N") { value = "Knots"; } else { value = "reserved"; } } if (pitem.Id == 0xE || pitem.Id == 0x10 || pitem.Id == 0x17) { if (value == "T") { value = "True direction"; } else if (value == "M") { value = "Magnetic direction"; } else { value = "reserved"; } } break; case 0x3: { #region 3 = SHORT (16-bit unsigned int) UInt16 uintval = BitConverter.ToUInt16(pitem.Value, 0); // orientation // lookup table switch (pitem.Id) { case 0x8827: // ISO speed rating value = "ISO-" + uintval.ToString(); break; case 0xA217: // sensing method { switch (uintval) { case 1: value = "Not defined"; break; case 2: value = "One-chip color area sensor"; break; case 3: value = "Two-chip color area sensor"; break; case 4: value = "Three-chip color area sensor"; break; case 5: value = "Color sequential area sensor"; break; case 7: value = "Trilinear sensor"; break; case 8: value = "Color sequential linear sensor"; break; default: value = " reserved"; break; } } break; case 0x8822: // 曝光程序 switch (uintval) { case 0: value = "未定义"; break; case 1: value = "手工"; break; case 2: value = "标准程序"; break; case 3: value = "光圈优先"; break; case 4: value = "快门优先"; break; case 5: value = "景深优先"; break; case 6: value = "运动模式"; break; case 7: value = "肖像模式"; break; case 8: value = "风景模式"; break; default: value = "保留"; break; } break; case 0x9207: // 测光模式 switch (uintval) { case 0: value = "未知"; break; case 1: value = "平均"; break; case 2: value = "中央重点平均"; break; case 3: value = "点测"; break; case 4: value = "多点"; break; case 5: value = "评估"; break; case 6: value = "局部"; break; case 255: value = "其他"; break; default: value = "保留"; break; } break; case 0x9208: // Light source { switch (uintval) { case 0: value = "unknown"; break; case 1: value = "Daylight"; break; case 2: value = "Fluorescent"; break; case 3: value = "Tungsten (incandescent light)"; break; case 4: value = "Flash"; break; case 9: value = "Fine weather"; break; case 10: value = "Cloudy weather"; break; case 11: value = "Shade"; break; case 12: value = "Daylight fluorescent (D 5700 – 7100K)"; break; case 13: value = "Day white fluorescent (N 4600 – 5400K)"; break; case 14: value = "Cool white fluorescent (W 3900 – 4500K)"; break; case 15: value = "White fluorescent (WW 3200 – 3700K)"; break; case 17: value = "Standard light A"; break; case 18: value = "Standard light B"; break; case 19: value = "Standard light C"; break; case 20: value = "D55"; break; case 21: value = "D65"; break; case 22: value = "D75"; break; case 23: value = "D50"; break; case 24: value = "ISO studio tungsten"; break; case 255: value = "ISO studio tungsten"; break; default: value = "other light source"; break; } } break; case 0x9209: // Flash { switch (uintval) { case 0x0: value = "关闭"; break; case 0x1: value = "Flash fired"; break; case 0x5: value = "Strobe return light not detected"; break; case 0x7: value = "Strobe return light detected"; break; case 0x9: value = "Flash fired, compulsory flash mode"; break; case 0xD: value = "Flash fired, compulsory flash mode, return light not detected"; break; case 0xF: value = "Flash fired, compulsory flash mode, return light detected"; break; case 0x10: value = "Flash did not fire, compulsory flash mode"; break; case 0x18: value = "Flash did not fire, auto mode"; break; case 0x19: value = "Flash fired, auto mode"; break; case 0x1D: value = "Flash fired, auto mode, return light not detected"; break; case 0x1F: value = "Flash fired, auto mode, return light detected"; break; case 0x20: value = "No flash function"; break; case 0x41: value = "Flash fired, red-eye reduction mode"; break; case 0x45: value = "Flash fired, red-eye reduction mode, return light not detected"; break; case 0x47: value = "Flash fired, red-eye reduction mode, return light detected"; break; case 0x49: value = "Flash fired, compulsory flash mode, red-eye reduction mode"; break; case 0x4D: value = "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected"; break; case 0x4F: value = "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected"; break; case 0x59: value = "Flash fired, auto mode, red-eye reduction mode"; break; case 0x5D: value = "Flash fired, auto mode, return light not detected, red-eye reduction mode"; break; case 0x5F: value = "Flash fired, auto mode, return light detected, red-eye reduction mode"; break; default: value = "reserved"; break; } } break; case 0x0128: //ResolutionUnit { switch (uintval) { case 2: value = "Inch"; break; case 3: value = "Centimeter"; break; default: value = "No Unit"; break; } } break; case 0xA409: // Saturation { switch (uintval) { case 0: value = "Normal"; break; case 1: value = "Low saturation"; break; case 2: value = "High saturation"; break; default: value = "Reserved"; break; } } break; case 0xA40A: // Sharpness { switch (uintval) { case 0: value = "Normal"; break; case 1: value = "Soft"; break; case 2: value = "Hard"; break; default: value = "Reserved"; break; } } break; case 0xA408: // Contrast { switch (uintval) { case 0: value = "Normal"; break; case 1: value = "Soft"; break; case 2: value = "Hard"; break; default: value = "Reserved"; break; } } break; case 0x103: // Compression { switch (uintval) { case 1: value = "Uncompressed"; break; case 6: value = "JPEG compression (thumbnails only)"; break; default: value = "Reserved"; break; } } break; case 0x106: // PhotometricInterpretation { switch (uintval) { case 2: value = "RGB"; break; case 6: value = "YCbCr"; break; default: value = "Reserved"; break; } } break; case 0x112: // Orientation { switch (uintval) { case 1: value = "The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side."; break; case 2: value = "The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side."; break; case 3: value = "The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side."; break; case 4: value = "The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side."; break; case 5: value = "The 0th row is the visual left-hand side of the image, and the 0th column is the visual top."; break; case 6: value = "The 0th row is the visual right-hand side of the image, and the 0th column is the visual top."; break; case 7: value = "The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom."; break; case 8: value = "The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom."; break; default: value = "Reserved"; break; } } break; case 0x213: // YCbCrPositioning { switch (uintval) { case 1: value = "centered"; break; case 6: value = "co-sited"; break; default: value = "Reserved"; break; } } break; case 0xA001: // ColorSpace { switch (uintval) { case 1: value = "sRGB"; break; case 0xFFFF: value = "Uncalibrated"; break; default: value = "Reserved"; break; } } break; case 0xA401: // CustomRendered { switch (uintval) { case 0: value = "Normal process"; break; case 1: value = "Custom process"; break; default: value = "Reserved"; break; } } break; case 0xA402: // ExposureMode { switch (uintval) { case 0: value = "Auto exposure"; break; case 1: value = "Manual exposure"; break; case 2: value = "Auto bracket"; break; default: value = "Reserved"; break; } } break; case 0xA403: // WhiteBalance { switch (uintval) { case 0: value = "Auto white balance"; break; case 1: value = "Manual white balance"; break; default: value = "Reserved"; break; } } break; case 0xA406: // SceneCaptureType { switch (uintval) { case 0: value = "Standard"; break; case 1: value = "Landscape"; break; case 2: value = "Portrait"; break; case 3: value = "Night scene"; break; default: value = "Reserved"; break; } } break; case 0xA40C: // SubjectDistanceRange { switch (uintval) { case 0: value = "unknown"; break; case 1: value = "Macro"; break; case 2: value = "Close view"; break; case 3: value = "Distant view"; break; default: value = "Reserved"; break; } } break; case 0x1E: // GPSDifferential { switch (uintval) { case 0: value = "Measurement without differential correction"; break; case 1: value = "Differential correction applied"; break; default: value = "Reserved"; break; } } break; case 0xA405: // FocalLengthIn35mmFilm value = uintval + " mm"; break; default: // value = uintval.ToString(); break; } #endregion } break; case 0x4: value = BitConverter.ToUInt32(pitem.Value, 0).ToString(); break; case 0x5: { #region 5 = RATIONAL (Two LONGs, unsigned) var rat = new URational(pitem.Value); switch (pitem.Id) { case 0x9202: // ApertureValue value = "F/" + Math.Round(Math.Pow(Math.Sqrt(2), rat.ToDouble()), 2).ToString(); break; case 0x9205: // MaxApertureValue value = "F/" + Math.Round(Math.Pow(Math.Sqrt(2), rat.ToDouble()), 2).ToString(); break; case 0x920A: // FocalLength value = rat.ToDouble().ToString() + " mm"; break; case 0x829D: // F-number value = "F/" + rat.ToDouble().ToString(); break; case 0x11A: // Xresolution value = rat.ToDouble().ToString(); break; case 0x11B: // Yresolution value = rat.ToDouble().ToString(); break; case 0x829A: // ExposureTime value = rat.ToString() + " sec"; break; case 0x2: // GPSLatitude value = new GPSRational(pitem.Value).ToString(); break; case 0x4: // GPSLongitude value = new GPSRational(pitem.Value).ToString(); break; case 0x6: // GPSAltitude value = rat.ToDouble() + " meters"; break; case 0xA404: // Digital Zoom Ratio value = rat.ToDouble().ToString(); if (value == "0") { value = "none"; } break; case 0xB: // GPSDOP value = rat.ToDouble().ToString(); break; case 0xD: // GPSSpeed value = rat.ToDouble().ToString(); break; case 0xF: // GPSTrack value = rat.ToDouble().ToString(); break; case 0x11: // GPSImgDir value = rat.ToDouble().ToString(); break; case 0x14: // GPSDestLatitude value = new GPSRational(pitem.Value).ToString(); break; case 0x16: // GPSDestLongitude value = new GPSRational(pitem.Value).ToString(); break; case 0x18: // GPSDestBearing value = rat.ToDouble().ToString(); break; case 0x1A: // GPSDestDistance value = rat.ToDouble().ToString(); break; case 0x7: // GPSTimeStamp value = new GPSRational(pitem.Value).ToString(":"); break; default: value = rat.ToString(); break; } #endregion } break; case 0x7: switch (pitem.Id) { case 0xA300: //FileSource { value = pitem.Value[0] == 3 ? "DSC" : "reserved"; break; } case 0xA301: //SceneType value = pitem.Value[0] == 1 ? "A directly photographed image" : "reserved"; break; case 0x9000: // Exif Version value = Ascii.GetString(pitem.Value).Trim('\0'); break; case 0xA000: // Flashpix Version value = Ascii.GetString(pitem.Value).Trim('\0'); value = value == "0100" ? "Flashpix Format Version 1.0" : "reserved"; break; case 0x9101: //ComponentsConfiguration value = GetComponentsConfig(pitem.Value); break; case 0x927C: //MakerNote value = Ascii.GetString(pitem.Value).Trim('\0'); break; case 0x9286: //UserComment value = Ascii.GetString(pitem.Value).Trim('\0'); break; case 0x1B: //GPS Processing Method value = Ascii.GetString(pitem.Value).Trim('\0'); break; case 0x1C: //GPS Area Info value = Ascii.GetString(pitem.Value).Trim('\0'); break; default: value = "-"; break; } break; case 0x9: value = BitConverter.ToInt32(pitem.Value, 0).ToString(); break; case 0xA: { #region 10 = SRATIONAL (Two SLONGs, signed) var rat = new Rational(pitem.Value); switch (pitem.Id) { case 0x9201: // ShutterSpeedValue value = "1/" + Math.Round(Math.Pow(2, rat.ToDouble()), 2).ToString(); break; case 0x9203: // BrightnessValue value = Math.Round(rat.ToDouble(), 4).ToString(); break; case 0x9204: // ExposureBiasValue value = Math.Round(rat.ToDouble(), 2).ToString() + " eV"; break; default: value = rat.ToString(); break; } #endregion } break; } return(value); }