public byte[] CreateExifBlob() { IFDInfo ifdInfo = BuildIFDEntries(); Dictionary <MetadataSection, IFDEntryInfo> ifdEntries = ifdInfo.IFDEntries; byte[] exifBytes = new byte[checked ((int)ifdInfo.EXIFDataLength)]; using (MemoryStream stream = new MemoryStream(exifBytes)) using (BinaryWriter writer = new BinaryWriter(stream)) { IFDEntryInfo imageInfo = ifdEntries[MetadataSection.Image]; IFDEntryInfo exifInfo = ifdEntries[MetadataSection.Exif]; writer.Write(TiffConstants.LittleEndianByteOrderMarker); writer.Write(TiffConstants.Signature); writer.Write((uint)imageInfo.StartOffset); WriteDirectory(writer, metadata[MetadataSection.Image], imageInfo.IFDEntries, imageInfo.StartOffset); WriteDirectory(writer, metadata[MetadataSection.Exif], exifInfo.IFDEntries, exifInfo.StartOffset); if (ifdEntries.TryGetValue(MetadataSection.Interop, out IFDEntryInfo interopInfo)) { WriteDirectory(writer, metadata[MetadataSection.Interop], interopInfo.IFDEntries, interopInfo.StartOffset); } if (ifdEntries.TryGetValue(MetadataSection.Gps, out IFDEntryInfo gpsInfo)) { WriteDirectory(writer, metadata[MetadataSection.Gps], gpsInfo.IFDEntries, gpsInfo.StartOffset); } } return(exifBytes); }
private IFDInfo CreateIFDInfo( IFDEntryInfo imageIFDInfo, IFDEntryInfo exifIFDInfo, IFDEntryInfo interopIFDInfo, IFDEntryInfo gpsIFDInfo) { Dictionary <MetadataSection, IFDEntryInfo> entries = new Dictionary <MetadataSection, IFDEntryInfo> { { MetadataSection.Image, imageIFDInfo }, { MetadataSection.Exif, exifIFDInfo } }; long dataLength = exifIFDInfo.NextAvailableOffset; if (interopIFDInfo != null) { entries.Add(MetadataSection.Interop, interopIFDInfo); dataLength = interopIFDInfo.NextAvailableOffset; } if (gpsIFDInfo != null) { entries.Add(MetadataSection.Gps, gpsIFDInfo); dataLength = gpsIFDInfo.NextAvailableOffset; } return(new IFDInfo(entries, dataLength)); }
private IFDInfo CalculateSectionOffsets() { IFDEntryInfo imageIFDInfo = CreateIFDList(metadata[MetadataSection.Image], FirstIFDOffset); IFDEntryInfo exifIFDInfo = CreateIFDList(metadata[MetadataSection.Exif], imageIFDInfo.NextAvailableOffset); IFDEntryInfo interopIFDInfo = null; IFDEntryInfo gpsIFDInfo = null; UpdateSubIFDOffset(ref imageIFDInfo, MetadataKeys.Image.ExifTag.TagId, (uint)exifIFDInfo.StartOffset); if (metadata.TryGetValue(MetadataSection.Interop, out Dictionary <ushort, MetadataEntry> interopSection)) { interopIFDInfo = CreateIFDList(interopSection, exifIFDInfo.NextAvailableOffset); UpdateSubIFDOffset(ref exifIFDInfo, MetadataKeys.Exif.InteroperabilityTag.TagId, (uint)interopIFDInfo.StartOffset); } if (metadata.TryGetValue(MetadataSection.Gps, out Dictionary <ushort, MetadataEntry> gpsSection)) { long startOffset = interopIFDInfo?.NextAvailableOffset ?? exifIFDInfo.NextAvailableOffset; gpsIFDInfo = CreateIFDList(gpsSection, startOffset); UpdateSubIFDOffset(ref imageIFDInfo, MetadataKeys.Image.GPSTag.TagId, (uint)gpsIFDInfo.StartOffset); } return(CreateIFDInfo(imageIFDInfo, exifIFDInfo, interopIFDInfo, gpsIFDInfo)); }
private static void UpdateSubIFDOffset(ref IFDEntryInfo ifdInfo, ushort tagId, uint newOffset) { int index = ifdInfo.IFDEntries.FindIndex(i => i.Tag == tagId); if (index != -1) { ifdInfo.IFDEntries[index] = new IFDEntry(tagId, TagDataType.Long, 1, newOffset); } }
private static IFDInfo CreateIFDInfo( IFDEntryInfo imageIFDInfo, IFDEntryInfo exifIFDInfo, IFDEntryInfo interopIFDInfo, IFDEntryInfo gpsIFDInfo) { Dictionary <ExifSection, IFDEntryInfo> entries = new() { { ExifSection.Image, imageIFDInfo }, { ExifSection.Photo, exifIFDInfo } };