public void Parse_ThumbnailData() { var dir = new ExifThumbnailDirectory(); dir.Set(ExifThumbnailDirectory.TagThumbnailOffset, 0); dir.Set(ExifThumbnailDirectory.TagThumbnailLength, 2); var segment = new JpegSegment(JpegSegmentType.App1, new byte[] { (byte)'E', (byte)'x', (byte)'i', (byte)'f', (byte)'\0', (byte)'\0', 0x12, 0x23, 0x34 }, 0); var metadata = new Mock <IExifMetadata>(); metadata.Setup(mock => mock.Segment).Returns(segment); metadata.Setup(mock => mock.GetDirectoryOfType <ExifDirectoryBase>()).Returns(dir); var parser = new ThumbnaiExifAttributeParser <ExifDirectoryBase>("thumbnail"); var thumbnail = parser.Parse(metadata.Object).Value as ImageValue; CollectionAssert.AreEqual(new byte[] { 0x12, 0x23 }, thumbnail.Value); }
public OffsetModel ParseOffsetData(ExifThumbnailDirectory exifThumbnailDir, string subPath) { return(new OffsetModel { Success = true }); }
/* * [Interoperability] Interoperability Index = Recommended Exif Interoperability Rules (ExifR98) * [Interoperability] Interoperability Version = 1.00 * [Jpeg] Data Precision = 8 bits * [Jpeg] Image Width = 600 pixels * [Jpeg] Image Height = 800 pixels * [Jpeg] Number of Components = 3 * [Jpeg] Component 1 = Y component: Quantization table 0, Sampling factors 1 horiz/1 vert * [Jpeg] Component 2 = Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert * [Jpeg] Component 3 = Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert */ public NikonType1MakernoteTest() { var metadata = ExifReaderTest.ProcessSegmentBytes("Tests/Data/nikonMakernoteType1.jpg.app1").ToList(); _nikonDirectory = metadata.OfType <NikonType1MakernoteDirectory>().SingleOrDefault(); _exifSubIfdDirectory = metadata.OfType <ExifSubIfdDirectory>().SingleOrDefault(); _exifIfd0Directory = metadata.OfType <ExifIfd0Directory>().SingleOrDefault(); _thumbDirectory = metadata.OfType <ExifThumbnailDirectory>().SingleOrDefault(); }
public void Parse_MissingOffsetTag() { var dir = new ExifThumbnailDirectory(); var metadata = new Mock <IExifMetadata>(); metadata.Setup(mock => mock.GetDirectoryOfType <ExifDirectoryBase>()).Returns(dir); var parser = new ThumbnaiExifAttributeParser <ExifDirectoryBase>("thumbnail"); Assert.IsNull(parser.Parse(metadata.Object)); }
public void GetDirectoryOfType_CorrectDirectory() { var firstDir = new ExifIfd0Directory(); var secondDir = new ExifThumbnailDirectory(); var directories = new List <Directory> { firstDir, secondDir }; var metadata = new ExifMetadata(null, directories); Assert.AreEqual(firstDir, metadata.GetDirectoryOfType <ExifIfd0Directory>()); }
public OffsetModel ParseOffsetData(ExifThumbnailDirectory exifThumbnailDir, string subPath) { if (exifThumbnailDir == null) { return new OffsetModel { Success = false, Reason = "ExifThumbnailDirectory null" } } ; long thumbnailOffset = long.Parse(exifThumbnailDir.GetDescription( ExifThumbnailDirectory.TagThumbnailOffset).Split(' ')[0]); const int maxIssue35Offset = 12; int thumbnailLength = int.Parse(exifThumbnailDir.GetDescription( ExifThumbnailDirectory.TagThumbnailLength).Split(' ')[0]) + maxIssue35Offset; byte[] thumbnail = new byte[thumbnailLength]; using (var imageStream = _iStorage.ReadStream(subPath)) { imageStream.Seek(thumbnailOffset, SeekOrigin.Begin); imageStream.Read(thumbnail, 0, thumbnailLength); } // work around Metadata Extractor issue #35 if (thumbnailLength <= maxIssue35Offset + 1) { _logger.LogInformation($"[ParseOffsetData] thumbnailLength : {thumbnailLength} {maxIssue35Offset + 1}"); return(new OffsetModel { Success = false, Reason = "offsetLength" }); } int issue35Offset = 0; for (int offset = 0; offset <= maxIssue35Offset; ++offset) { // 0xffd8 is the JFIF start of image segment indicator if ((thumbnail[offset] == 0xff) && (thumbnail[offset + 1] == 0xd8)) { issue35Offset = offset; break; } } return(new OffsetModel { Success = true, Index = issue35Offset, Count = thumbnailLength - issue35Offset, Data = thumbnail, // byte array }); } }
public void GetYCbCrSubsamplingDescription() { var directory = new ExifThumbnailDirectory(); var descriptor = new ExifThumbnailDescriptor(directory); directory.Set(ExifDirectoryBase.TagYCbCrSubsampling, new[] { 2, 1 }); Assert.Equal("YCbCr4:2:2", descriptor.GetDescription(ExifDirectoryBase.TagYCbCrSubsampling)); Assert.Equal("YCbCr4:2:2", descriptor.GetYCbCrSubsamplingDescription()); directory.Set(ExifDirectoryBase.TagYCbCrSubsampling, new[] { 2, 2 }); Assert.Equal("YCbCr4:2:0", descriptor.GetDescription(ExifDirectoryBase.TagYCbCrSubsampling)); Assert.Equal("YCbCr4:2:0", descriptor.GetYCbCrSubsamplingDescription()); }
public void TestGetDirectoryName() { Directory subIfdDirectory = new ExifSubIfdDirectory(); Directory ifd0Directory = new ExifIfd0Directory(); Directory thumbDirectory = new ExifThumbnailDirectory(); Assert.False(subIfdDirectory.HasError); Assert.False(ifd0Directory.HasError); Assert.False(thumbDirectory.HasError); Assert.Equal("Exif IFD0", ifd0Directory.Name); Assert.Equal("Exif SubIFD", subIfdDirectory.Name); Assert.Equal("Exif Thumbnail", thumbDirectory.Name); }
protected ImageSource ReadThumbnailFromExif(String filename, ExifThumbnailDirectory thumbnails) { if (thumbnails == null) { return(null); } //Assert.IsTrue(thumbnails.GetDescription(ExifThumbnailDirectory.TagCompression).StartsWith("JPEG")); long thumbnailOffset = Int64.Parse(thumbnails.GetDescription(ExifThumbnailDirectory.TagThumbnailOffset).Split(' ')[0]); const int maxIssue35Offset = 12; int thumbnailLength = Int32.Parse(thumbnails.GetDescription(ExifThumbnailDirectory.TagThumbnailLength).Split(' ')[0]) + maxIssue35Offset; byte[] thumbnail = new byte[thumbnailLength]; using (FileStream imageStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { imageStream.Seek(thumbnailOffset, SeekOrigin.Begin); imageStream.Read(thumbnail, 0, thumbnailLength); } // work around Metadata Extractor issue #35 //Assert.IsTrue(thumbnailLength > maxIssue35Offset + 1); int issue35Offset = 0; for (int offset = 0; offset <= maxIssue35Offset; ++offset) { // 0xffd8 is the JFIF start of image segment indicator if ((thumbnail[offset] == 0xff) && (thumbnail[offset + 1] == 0xd8)) { issue35Offset = offset; break; } } using (MemoryStream thumbnailStream = new MemoryStream(thumbnail, issue35Offset, thumbnailLength - issue35Offset, false)) { JpegBitmapDecoder jpegDecoder = new JpegBitmapDecoder(thumbnailStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); WriteableBitmap writeableBitmap = new WriteableBitmap(jpegDecoder.Frames[0]); writeableBitmap.Freeze(); return(writeableBitmap); } }
internal Row(MarkdownTableOutputHandler _enclosing, [NotNull] FilePath file, [NotNull] Com.Drew.Metadata.Metadata metadata, [NotNull] string relativePath) { this._enclosing = _enclosing; this.file = file; this.metadata = metadata; this.relativePath = relativePath; ExifIFD0Directory ifd0Dir = metadata.GetFirstDirectoryOfType <ExifIFD0Directory>(); ExifSubIFDDirectory subIfdDir = metadata.GetFirstDirectoryOfType <ExifSubIFDDirectory>(); ExifThumbnailDirectory thumbDir = metadata.GetFirstDirectoryOfType <ExifThumbnailDirectory>(); if (ifd0Dir != null) { this.manufacturer = ifd0Dir.GetDescription(ExifIFD0Directory.TagMake); this.model = ifd0Dir.GetDescription(ExifIFD0Directory.TagModel); } bool hasMakernoteData = false; if (subIfdDir != null) { this.exifVersion = subIfdDir.GetDescription(ExifSubIFDDirectory.TagExifVersion); hasMakernoteData = subIfdDir.ContainsTag(ExifSubIFDDirectory.TagMakernote); } if (thumbDir != null) { int?width = thumbDir.GetInteger(ExifThumbnailDirectory.TagImageWidth); int?height = thumbDir.GetInteger(ExifThumbnailDirectory.TagImageHeight); this.thumbnail = width != null && height != null?Sharpen.Extensions.StringFormat("Yes (%s x %s)", width, height) : "Yes"; } foreach (Com.Drew.Metadata.Directory directory in metadata.GetDirectories()) { if (directory.GetType().FullName.Contains("Makernote")) { this.makernote = Sharpen.Extensions.Trim(directory.GetName().Replace("Makernote", string.Empty)); } } if (this.makernote == null) { this.makernote = hasMakernoteData ? "(Unknown)" : "N/A"; } }
internal (ExifThumbnailDirectory, int, int, FileIndexItem.Rotation) ParseMetaThumbnail(List <Directory> allExifItems, ExifThumbnailDirectory exifThumbnailDir, string reference = null) { if (exifThumbnailDir == null) { return(null, 0, 0, FileIndexItem.Rotation.DoNotChange); } var jpegTags = allExifItems.FirstOrDefault(p => p.Name == "JPEG")?.Tags; var rotation = ReadMetaExif.GetOrientationFromExifItem( allExifItems.FirstOrDefault(p => p.Name == "Exif IFD0")); int.TryParse( jpegTags?.FirstOrDefault(p => p.Name == "Image Height")? .Description.Replace(" pixels", string.Empty), out var height); int.TryParse( jpegTags?.FirstOrDefault(p => p.Name == "Image Width")? .Description.Replace(" pixels", string.Empty), out var width); if (height == 0 || width == 0) { _logger.LogInformation($"[] ${reference} has no height or width {width}x{height} "); } return(exifThumbnailDir, width, height, rotation); }
/// <summary>An application entry point.</summary> /// <remarks> /// An application entry point. Takes the name of one or more files as arguments and prints the contents of all /// metadata directories to <code>System.out</code>. /// <p/> /// If <code>-thumb</code> is passed, then any thumbnail data will be written to a file with name of the /// input file having <code>.thumb.jpg</code> appended. /// <p/> /// If <code>-wiki</code> is passed, then output will be in a format suitable for Google Code's wiki. /// <p/> /// If <code>-hex</code> is passed, then the ID of each tag will be displayed in hexadecimal. /// </remarks> /// <param name="args">the command line arguments</param> /// <exception cref="Com.Drew.Metadata.MetadataException"/> /// <exception cref="System.IO.IOException"/> public static void Main(string[] args) { ICollection <string> argList = new AList <string>(Arrays.AsList(args)); bool thumbRequested = argList.Remove("-thumb"); bool wikiFormat = argList.Remove("-wiki"); bool showHex = argList.Remove("-hex"); if (argList.Count < 1) { string version = typeof(Com.Drew.Imaging.ImageMetadataReader).Assembly.GetImplementationVersion(); System.Console.Out.Println("metadata-extractor version " + version); System.Console.Out.Println(); System.Console.Out.Println(Sharpen.Extensions.StringFormat("Usage: java -jar metadata-extractor-%s.jar <filename> [<filename>] [-thumb] [-wiki] [-hex]", version == null ? "a.b.c" : version)); System.Environment.Exit(1); } foreach (string filePath in argList) { long startTime = Runtime.NanoTime(); FilePath file = new FilePath(filePath); if (!wikiFormat && argList.Count > 1) { System.Console.Out.Printf("\n***** PROCESSING: %s\n%n", filePath); } Com.Drew.Metadata.Metadata metadata = null; try { metadata = Com.Drew.Imaging.ImageMetadataReader.ReadMetadata(file); } catch (Exception e) { Sharpen.Runtime.PrintStackTrace(e, System.Console.Error); System.Environment.Exit(1); } long took = Runtime.NanoTime() - startTime; if (!wikiFormat) { System.Console.Out.Printf("Processed %.3f MB file in %.2f ms%n%n", file.Length() / (1024d * 1024), took / 1000000d); } if (wikiFormat) { string fileName = file.GetName(); string urlName = StringUtil.UrlEncode(fileName); ExifIFD0Directory exifIFD0Directory = metadata.GetDirectory <ExifIFD0Directory>(); string make = exifIFD0Directory == null ? string.Empty : StringUtil.EscapeForWiki(exifIFD0Directory.GetString(ExifIFD0Directory.TagMake)); string model = exifIFD0Directory == null ? string.Empty : StringUtil.EscapeForWiki(exifIFD0Directory.GetString(ExifIFD0Directory.TagModel)); System.Console.Out.Println(); System.Console.Out.Println("-----"); System.Console.Out.Println(); System.Console.Out.Printf("= %s - %s =%n", make, model); System.Console.Out.Println(); System.Console.Out.Printf("<a href=\"http://sample-images.metadata-extractor.googlecode.com/git/%s\">%n", urlName); System.Console.Out.Printf("<img src=\"http://sample-images.metadata-extractor.googlecode.com/git/%s\" width=\"300\"/><br/>%n", urlName); System.Console.Out.Println(StringUtil.EscapeForWiki(fileName)); System.Console.Out.Println("</a>"); System.Console.Out.Println(); System.Console.Out.Println("|| *Directory* || *Tag Id* || *Tag Name* || *Extracted Value* ||"); } // iterate over the metadata and print to System.out foreach (Com.Drew.Metadata.Directory directory in metadata.GetDirectories()) { string directoryName = directory.GetName(); foreach (Tag tag in directory.GetTags()) { string tagName = tag.GetTagName(); string description = tag.GetDescription(); // truncate the description if it's too long if (description != null && description.Length > 1024) { description = Sharpen.Runtime.Substring(description, 0, 1024) + "..."; } if (wikiFormat) { System.Console.Out.Printf("||%s||0x%s||%s||%s||%n", StringUtil.EscapeForWiki(directoryName), Sharpen.Extensions.ToHexString(tag.GetTagType()), StringUtil.EscapeForWiki(tagName), StringUtil.EscapeForWiki(description)); } else { if (showHex) { System.Console.Out.Printf("[%s - %s] %s = %s%n", directoryName, tag.GetTagTypeHex(), tagName, description); } else { System.Console.Out.Printf("[%s] %s = %s%n", directoryName, tagName, description); } } } // print out any errors foreach (string error in directory.GetErrors()) { System.Console.Error.Println("ERROR: " + error); } } if (args.Length > 1 && thumbRequested) { ExifThumbnailDirectory directory_1 = metadata.GetDirectory <ExifThumbnailDirectory>(); if (directory_1 != null && directory_1.HasThumbnailData()) { System.Console.Out.Println("Writing thumbnail..."); directory_1.WriteThumbnail(Sharpen.Extensions.Trim(args[0]) + ".thumb.jpg"); } else { System.Console.Out.Println("No thumbnail data exists in this image"); } } } }