using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Infrastructure.Helpers { using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Text; public class ExifReader { // Exif 标签ID与名称的映射字典(部分常见标签) private static readonly Dictionary ExifTags = new Dictionary { { 0x010E, "ImageDescription" }, { 0x010F, "Make" }, { 0x0110, "Model" }, { 0x0112, "Orientation" }, { 0x011A, "XResolution" }, { 0x011B, "YResolution" }, { 0x0128, "ResolutionUnit" }, { 0x0131, "Software" }, { 0x0132, "DateTime" }, { 0x0213, "YCbCrPositioning" }, { 0x8769, "ExifIFD" }, { 0x829A, "ExposureTime" }, { 0x829D, "FNumber" }, { 0x8822, "ExposureProgram" }, { 0x8827, "ISOSpeedRatings" }, { 0x9000, "ExifVersion" }, { 0x9003, "DateTimeOriginal" }, { 0x9004, "DateTimeDigitized" }, { 0x9101, "ComponentsConfiguration" }, { 0x9201, "ShutterSpeedValue" }, { 0x9202, "ApertureValue" }, { 0x9203, "BrightnessValue" }, { 0x9204, "ExposureBiasValue" }, { 0x9205, "MaxApertureValue" }, { 0x9206, "SubjectDistance" }, { 0x9207, "MeteringMode" }, { 0x9208, "LightSource" }, { 0x9209, "Flash" }, { 0x920A, "FocalLength" }, { 0x927C, "MakerNote" }, { 0x9286, "UserComment" }, { 0x9290, "SubsecTime" }, { 0x9291, "SubsecTimeOriginal" }, { 0x9292, "SubsecTimeDigitized" }, { 0xA000, "FlashpixVersion" }, { 0xA001, "ColorSpace" }, { 0xA002, "PixelXDimension" }, { 0xA003, "PixelYDimension" }, { 0xA004, "RelatedSoundFile" }, { 0xA005, "InteroperabilityIFD" }, { 0xA20B, "FlashEnergy" }, { 0xA20C, "SpatialFrequencyResponse" }, { 0xA20E, "FocalPlaneXResolution" }, { 0xA20F, "FocalPlaneYResolution" }, { 0xA210, "FocalPlaneResolutionUnit" }, { 0xA214, "SubjectLocation" }, { 0xA215, "ExposureIndex" }, { 0xA217, "SensingMethod" }, { 0xA300, "FileSource" }, { 0xA301, "SceneType" }, { 0xA302, "CFAPattern" }, { 0xA401, "CustomRendered" }, { 0xA402, "ExposureMode" }, { 0xA403, "WhiteBalance" }, { 0xA404, "DigitalZoomRatio" }, { 0xA405, "FocalLengthIn35mmFilm" }, { 0xA406, "SceneCaptureType" }, { 0xA407, "GainControl" }, { 0xA408, "Contrast" }, { 0xA409, "Saturation" }, { 0xA40A, "Sharpness" }, { 0xA40B, "DeviceSettingDescription" }, { 0xA40C, "SubjectDistanceRange" }, { 0xA420, "ImageUniqueID" }, { 0xA431, "BodySerialNumber" }, { 0xA432, "LensSpecification" }, { 0xA433, "LensMake" }, { 0xA434, "LensModel" }, { 0xA435, "LensSerialNumber" }, { 0x8298, "Copyright" }, // 这是你特别关心的 Copyright 字段 { 0x013B, "Artist" }, { 0x9C9B, "WindowsTitle" }, { 0x9C9C, "WindowsComment" }, { 0x9C9D, "WindowsAuthor" }, { 0x9C9E, "WindowsKeywords" }, { 0x9C9F, "WindowsSubject" } }; public static Dictionary GetAllExifData(Stream imageStream) { var exifData = new Dictionary(); using (Image image = Image.FromStream(imageStream)) { foreach (PropertyItem propItem in image.PropertyItems) { string tagName = ExifTags.ContainsKey(propItem.Id) ? ExifTags[propItem.Id] : $"Unknown (0x{propItem.Id:X4})"; string value = InterpretExifValue(propItem); exifData[tagName] = value; } } return exifData; } private static string InterpretExifValue(PropertyItem propItem) { try { switch (propItem.Type) { case 1: // Byte array return $"Byte[{propItem.Len}]"; case 2: // ASCII string return Encoding.ASCII.GetString(propItem.Value).TrimEnd('\0'); case 3: // Unsigned short (16-bit) if (propItem.Len == 2) return BitConverter.ToUInt16(propItem.Value, 0).ToString(); break; case 4: // Unsigned long (32-bit) if (propItem.Len == 4) return BitConverter.ToUInt32(propItem.Value, 0).ToString(); break; case 5: // Unsigned rational (two 32-bit values: numerator/denominator) if (propItem.Len == 8) { uint numerator = BitConverter.ToUInt32(propItem.Value, 0); uint denominator = BitConverter.ToUInt32(propItem.Value, 4); return denominator != 0 ? $"{numerator}/{denominator}" : "Invalid rational"; } break; case 7: // Undefined return $"Undefined[{propItem.Len}]"; case 9: // Signed long (32-bit) if (propItem.Len == 4) return BitConverter.ToInt32(propItem.Value, 0).ToString(); break; case 10: // Signed rational (two 32-bit values: numerator/denominator) if (propItem.Len == 8) { int numerator = BitConverter.ToInt32(propItem.Value, 0); int denominator = BitConverter.ToInt32(propItem.Value, 4); return denominator != 0 ? $"{numerator}/{denominator}" : "Invalid rational"; } break; } return $"Type {propItem.Type}[{propItem.Len}]"; } catch (Exception ex) { return $"Error reading value: {ex.Message}"; } } // 专门获取 Copyright 信息的方法 public static string GetCopyright(Stream imageStream) { using (Image image = Image.FromStream(imageStream)) { try { // 0x8298 是 Copyright 的 Exif tag ID PropertyItem copyrightProp = image.GetPropertyItem(0x8298); return InterpretExifValue(copyrightProp); } catch (ArgumentException) { // 如果没有找到 Copyright 属性 return "No copyright information"; } } } } }