private void CreateAndShowMainWindow() { // Create the application's main window mainWindow = new Window(); mainWindow.Title = "Imaging Sample"; ScrollViewer mySV = new ScrollViewer(); //<Snippet1> int width = 128; int height = width; int stride = width / 8; byte[] pixels = new byte[height * stride]; // Try creating a new image with a custom palette. List <System.Windows.Media.Color> colors = new List <System.Windows.Media.Color>(); colors.Add(System.Windows.Media.Colors.Red); colors.Add(System.Windows.Media.Colors.Blue); colors.Add(System.Windows.Media.Colors.Green); BitmapPalette myPalette = new BitmapPalette(colors); // Creates a new empty image with the pre-defined palette //<Snippet2> BitmapSource image = BitmapSource.Create( width, height, 96, 96, PixelFormats.Indexed1, myPalette, pixels, stride); //</Snippet2> //<Snippet3> FileStream stream = new FileStream("empty.tif", FileMode.Create); TiffBitmapEncoder encoder = new TiffBitmapEncoder(); TextBlock myTextBlock = new TextBlock(); myTextBlock.Text = "Codec Author is: " + encoder.CodecInfo.Author.ToString(); encoder.Frames.Add(BitmapFrame.Create(image)); MessageBox.Show(myPalette.Colors.Count.ToString()); encoder.Save(stream); //</Snippet3> //</Snippet1> // Draw the Image Image myImage = new Image(); myImage.Source = image; myImage.Stretch = Stretch.None; myImage.Margin = new Thickness(20); //<Snippet4> // Open a Stream and decode a TIFF image Stream imageStreamSource = new FileStream("tulipfarm.tif", FileMode.Open, FileAccess.Read, FileShare.Read); TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); BitmapSource bitmapSource = decoder.Frames[0]; // Draw the Image Image myImage1 = new Image(); myImage1.Source = bitmapSource; myImage1.Stretch = Stretch.None; myImage1.Margin = new Thickness(20); //</Snippet4> //<Snippet5> // Get the palette from an image BitmapImage image2 = new BitmapImage(); image2.BeginInit(); image2.UriSource = new Uri("tulipfarm.tif", UriKind.RelativeOrAbsolute); image2.EndInit(); BitmapPalette myPalette3 = new BitmapPalette(image2, 256); //Draw the third Image Image myImage2 = new Image(); myImage2.Source = image2; myImage2.Stretch = Stretch.None; myImage2.Margin = new Thickness(20); //</Snippet5> //<Snippet6> //Create a new TIFF image based on existing Image FileStream stream2 = new FileStream("image.tif", FileMode.Create); TiffBitmapEncoder encoder2 = new TiffBitmapEncoder(); TiffBitmapDecoder decoder2 = new TiffBitmapDecoder(new Uri("tulipfarm.tif", UriKind.RelativeOrAbsolute), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None); encoder2.Frames = decoder2.Frames; //<Snippet7> BitmapMetadata tiffMetadata = new BitmapMetadata("tiff"); tiffMetadata.SetQuery("/ifd/{ushort=1000}", 9999); tiffMetadata.SetQuery("/ifd/{uint=1001}", 23456); tiffMetadata.SetQuery("/ifd/{uint=1002}", 34567); tiffMetadata.SetQuery("/ifd/PaddingSchema:padding", (UInt32)4096); tiffMetadata.SetQuery("/ifd/exif", new BitmapMetadata("exif")); tiffMetadata.SetQuery("/ifd/exif/PaddingSchema:padding", (UInt32)4096); //</Snippet7> encoder2.Save(stream2); stream2.Close(); //</Snippet6> //<Snippet9> FileStream stream4 = new FileStream("image3.tif", FileMode.Create); BitmapMetadata myBitmapMetadata2 = new BitmapMetadata("tiff"); TiffBitmapEncoder encoder4 = new TiffBitmapEncoder(); MessageBox.Show(myBitmapMetadata2.IsFixedSize.ToString()); MessageBox.Show(myBitmapMetadata2.IsReadOnly.ToString()); MessageBox.Show(myBitmapMetadata2.Format.ToString()); MessageBox.Show(myBitmapMetadata2.Location.ToString()); encoder4.Frames = decoder2.Frames; encoder4.Save(stream4); stream4.Close(); //</Snippet9> // <Snippet8> FileStream stream3 = new FileStream("image2.tif", FileMode.Create); BitmapMetadata myBitmapMetadata = new BitmapMetadata("tiff"); TiffBitmapEncoder encoder3 = new TiffBitmapEncoder(); myBitmapMetadata.ApplicationName = "Microsoft Digital Image Suite 10"; myBitmapMetadata.Author = new ReadOnlyCollection <string>( new List <string>() { "Lori Kane" }); myBitmapMetadata.CameraManufacturer = "Tailspin Toys"; myBitmapMetadata.CameraModel = "TT23"; myBitmapMetadata.Comment = "Nice Picture"; myBitmapMetadata.Copyright = "2010"; myBitmapMetadata.DateTaken = "5/23/2010"; myBitmapMetadata.Keywords = new ReadOnlyCollection <string>( new List <string>() { "Lori", "Kane" }); myBitmapMetadata.Rating = 5; myBitmapMetadata.Subject = "Lori"; myBitmapMetadata.Title = "Lori's photo"; // Create a new frame that is identical to the one // from the original image, except for the new metadata. encoder3.Frames.Add( BitmapFrame.Create( decoder2.Frames[0], decoder2.Frames[0].Thumbnail, myBitmapMetadata, decoder2.Frames[0].ColorContexts)); encoder3.Save(stream3); stream3.Close(); // </Snippet8> //<Snippet10> BitmapSource image5 = BitmapSource.Create( width, height, 96, 96, PixelFormats.Indexed1, BitmapPalettes.WebPalette, pixels, stride); FileStream stream5 = new FileStream("palette.tif", FileMode.Create); TiffBitmapEncoder encoder5 = new TiffBitmapEncoder(); encoder5.Frames.Add(BitmapFrame.Create(image5)); encoder5.Save(stream5); //</Snippet10> // Define a StackPanel to host Content StackPanel myStackPanel = new StackPanel(); myStackPanel.Orientation = Orientation.Vertical; myStackPanel.VerticalAlignment = VerticalAlignment.Stretch; myStackPanel.HorizontalAlignment = HorizontalAlignment.Stretch; // Add the Image and TextBlock to the parent Grid myStackPanel.Children.Add(myImage); myStackPanel.Children.Add(myTextBlock); myStackPanel.Children.Add(myImage1); myStackPanel.Children.Add(myImage2); // Add the StackPanel as the Content of the Parent Window Object mySV.Content = myStackPanel; mainWindow.Content = mySV; mainWindow.Show(); }
private void WriteCopyOfPictureUsingWic(string originalFileName, string outputFileName) { bool tryOneLastMethod = false; using (Stream originalFile = new FileStream(originalFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile; BitmapDecoder original = BitmapDecoder.Create(originalFile, createOptions, BitmapCacheOption.None); JpegBitmapEncoder output = new JpegBitmapEncoder(); if (original.Frames[0] != null && original.Frames[0].Metadata != null) { BitmapMetadata bitmapMetadata = original.Frames[0].Metadata.Clone() as BitmapMetadata; bitmapMetadata.SetQuery("/app1/ifd/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES); bitmapMetadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES); bitmapMetadata.SetQuery("/xmp/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES); SetMetadata(bitmapMetadata); output.Frames.Add(BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, bitmapMetadata, original.Frames[0].ColorContexts)); } try { using (Stream outputFile = File.Open(outputFileName, FileMode.Create, FileAccess.ReadWrite)) { output.Save(outputFile); } } catch (NotSupportedException e) { System.Diagnostics.Debug.Print(e.Message); output = new JpegBitmapEncoder(); output.Frames.Add(BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, original.Metadata, original.Frames[0].ColorContexts)); using (Stream outputFile = File.Open(outputFileName, FileMode.Create, FileAccess.ReadWrite)) { output.Save(outputFile); } tryOneLastMethod = true; } } if (tryOneLastMethod) { File.Move(outputFileName, outputFileName + "tmp"); using (Stream recentlyOutputFile = new FileStream(outputFileName + "tmp", FileMode.Open, FileAccess.Read, FileShare.Read)) { BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile; BitmapDecoder original = BitmapDecoder.Create(recentlyOutputFile, createOptions, BitmapCacheOption.None); JpegBitmapEncoder output = new JpegBitmapEncoder(); if (original.Frames[0] != null && original.Frames[0].Metadata != null) { BitmapMetadata bitmapMetadata = original.Frames[0].Metadata.Clone() as BitmapMetadata; bitmapMetadata.SetQuery("/app1/ifd/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES); bitmapMetadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES); bitmapMetadata.SetQuery("/xmp/PaddingSchema:Padding", METADATA_PADDING_IN_BYTES); SetMetadata(bitmapMetadata); output.Frames.Add(BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, bitmapMetadata, original.Frames[0].ColorContexts)); } using (Stream outputFile = File.Open(outputFileName, FileMode.Create, FileAccess.ReadWrite)) { output.Save(outputFile); } } File.Delete(outputFileName + "tmp"); } }
static void CreatePng(TileSetLoader loader, string dstPath) { int numSymbols = EnumHelpers.GetEnumMax<SymbolID>() + 1; int[] tileSizes = new int[] { 8, 10, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96 }; int maxTileSize = tileSizes.Max(); WriteableBitmap target = new WriteableBitmap(tileSizes.Sum(), maxTileSize * numSymbols, 96, 96, PixelFormats.Bgra32, null); target.Lock(); // leave the first one (Undefined) empty for (int i = 1; i < numSymbols; ++i) { int xOffset = 0; foreach (int tileSize in tileSizes) { var source = loader.GetTileBitmap((SymbolID)i, tileSize); int stride = source.PixelWidth * (source.Format.BitsPerPixel / 8); byte[] data = new byte[stride * source.PixelHeight]; source.CopyPixels(data, stride, 0); target.WritePixels(new Int32Rect(xOffset, i * maxTileSize, tileSize, tileSize), data, stride, 0); xOffset += tileSize; } } target.Unlock(); string tileSizesStr = string.Join(",", tileSizes.Select(i => i.ToString())); var pngEncoder = new PngBitmapEncoder(); var metadata = new BitmapMetadata("png"); metadata.SetQuery("/tEXt/Software", "Dwarrowdelf"); metadata.SetQuery("/tEXt/tilesizes", tileSizesStr); var frame = BitmapFrame.Create(target, null, metadata, null); pngEncoder.Frames = new BitmapFrame[] { frame }; string path = Path.Combine(dstPath, "TileSet.png"); using (var stream = File.OpenWrite(path)) pngEncoder.Save(stream); Console.WriteLine("Generated TileSet to {0}", path); }
private void SetRotation(BitmapMetadata metadata, int rotation) { if (metadata == null) throw new ArgumentNullException("metadata"); int value = 1; switch(rotation) { case 0: value = 1; break; case 90: value = 6; break; case 180: value = 3; break; case 270: value = 8; break; default: throw new ArgumentException("rotation"); } metadata.SetQuery("System.Photo.Orientation", value); }
public static void SetImageMetadata(string imagesFolderPath) { string originalPath = @"C:\Users\test\Desktop\test.jpg"; string outputPath = Environment.CurrentDirectory + @"\output.jpg"; string finalPath = Environment.CurrentDirectory + @"\output_beforeInPlaceBitmapMetadataWriter.jpg"; BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile; uint paddingAmount = 2048; // 2Kb padding for this example, but really this can be any value. // Our recommendation is to keep this between 1Kb and 5Kb as most metadata updates are not large. // High level overview: // 1. Perform a lossles transcode on the JPEG // 2. Add appropriate padding // 3. Optionally add whatever metadata we need to add initially // 4. Save the file // 5. For sanity, we verify that we really did a lossless transcode // 6. Open the new file and add metadata in-place using (Stream originalFile = File.Open(originalPath, FileMode.Open, FileAccess.Read)) { // Notice the BitmapCreateOptions and BitmapCacheOption. Using these options in the manner here // will inform the JPEG decoder and encoder that we're doing a lossless transcode operation. If the // encoder is anything but a JPEG encoder, then this no longer is a lossless operation. // ( Details: Basically BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile // tell the decoder to use the original image bits and BitmapCacheOption.None tells the decoder to wait // with decoding. So, at the time of encoding the JPEG encoder understands that the input was a JPEG // and just copies over the image bits without decompressing and recompressing them. Hence, this is a // lossless operation. ) BitmapDecoder original = BitmapDecoder.Create(originalFile, createOptions, BitmapCacheOption.None); if (!original.CodecInfo.FileExtensions.Contains("jpg")) { Console.WriteLine("The file you passed in is not a JPEG."); return; } JpegBitmapEncoder output = new JpegBitmapEncoder(); // If you're just interested in doing a lossless transcode without adding metadata, just do this: //output.Frames = original.Frames; // If you want to add metadata to the image using the InPlaceBitmapMetadataWriter, first add padding: if (original.Frames[0] != null && original.Frames[0].Metadata != null) { // Your gut feel may want you to do something like: // output.Frames = original.Frames; // BitmapMetadata metadata = output.Frames[0].Metadata as BitmapMetadata; // if (metadata != null) // { // metadata.SetQuery("/app1/ifd/PaddingSchema:Padding", paddingAmount); // } // However, the BitmapMetadata object is frozen. So, you need to clone the BitmapMetadata and then // set the padding on it. Lastly, you need to create a "new" frame with the updated metadata. BitmapMetadata metadata = original.Frames[0].Metadata.Clone() as BitmapMetadata; // Of the metadata handlers that we ship in WIC, padding can only exist in IFD, EXIF, and XMP. // Third parties implementing their own metadata handler may wish to support IWICFastMetadataEncoder // and hence support padding as well. metadata.SetQuery("/app1/ifd/PaddingSchema:Padding", paddingAmount); metadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", paddingAmount); metadata.SetQuery("/xmp/PaddingSchema:Padding", paddingAmount); // Since you're already adding metadata now, you can go ahead and add metadata up front. metadata.SetQuery("/app1/ifd/{uint=897}", "hello there"); metadata.SetQuery("/app1/ifd/{uint=898}", "this is a test"); metadata.Title = "This is a title"; // Create a new frame identical to the one from the original image, except the metadata will have padding. // Essentially we want to keep this as close as possible to: // output.Frames = original.Frames; output.Frames.Add(BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, metadata, original.Frames[0].ColorContexts)); } using (Stream outputFile = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite)) { output.Save(outputFile); } } // For sanity, let's verify that the original and the output contain image bits that are the same. using (Stream originalFile = File.Open(originalPath, FileMode.Open, FileAccess.Read)) { BitmapDecoder original = BitmapDecoder.Create(originalFile, createOptions, BitmapCacheOption.None); using (Stream savedFile = File.Open(outputPath, FileMode.Open, FileAccess.Read)) { BitmapDecoder output = BitmapDecoder.Create(savedFile, createOptions, BitmapCacheOption.None); Compare(original.Frames[0], output.Frames[0], 0, "foo", Console.Out); } } // Let's copy the file before we use the InPlaceBitmapMetadataWriter so that you can verify the metadata changes. File.Copy(outputPath, finalPath, true); Console.WriteLine(); // Now let's use the InPlaceBitmapMetadataWriter. using (Stream savedFile = File.Open(outputPath, FileMode.Open, FileAccess.ReadWrite)) { ConsoleColor originalColor = Console.ForegroundColor; BitmapDecoder output = BitmapDecoder.Create(savedFile, BitmapCreateOptions.None, BitmapCacheOption.Default); InPlaceBitmapMetadataWriter metadata = output.Frames[0].CreateInPlaceBitmapMetadataWriter(); // Within the InPlaceBitmapMetadataWriter, you can add, update, or remove metadata. //metadata.SetQuery("/app1/ifd/{uint=899}", "this is a test of the InPlaceBitmapMetadataWriter"); //metadata.RemoveQuery("/app1/ifd/{uint=898}"); //metadata.SetQuery("/app1/ifd/{uint=897}", "Hello there!!"); Console.WriteLine("#####################"); Console.WriteLine(metadata.GetQuery(@"/app13/irb/8bimiptc/iptc/City")); Console.WriteLine("#####################"); metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/Headline", "TEst"); metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/City", "TEst"); metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/CountryPrimaryLocationName", "TEst"); metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/ByLine", "TEst"); metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/CaptionAbstract", "TEst"); Console.WriteLine("#####################"); Console.WriteLine(metadata.GetQuery(@"/app13/irb/8bimiptc/iptc/City")); Console.WriteLine("#####################"); if (metadata.TrySave()) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("InPlaceMetadataWriter succeeded!"); } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("InPlaceMetadataWriter failed!"); } Console.ForegroundColor = originalColor; } FileInfo originalInfo = new FileInfo(originalPath); FileInfo outputInfo = new FileInfo(outputPath); FileInfo finalInfo = new FileInfo(finalPath); Console.WriteLine(outputPath); Console.WriteLine(); Console.WriteLine("Original File Size: \t\t\t{0}", originalInfo.Length); Console.WriteLine("After Padding File Size: \t\t{0}", outputInfo.Length); Console.WriteLine("After InPlaceBitmapWriter File Size: \t{0}", finalInfo.Length); }
private static BitmapMetadata ConvertMetaDataToJPEG(BitmapMetadata metaData, string format) { BitmapMetadata exif = GetEXIFMetaData(metaData, format); BitmapMetadata xmp = GetXMPMetaData(metaData, format); BitmapMetadata iptc = GetIPTCMetaData(metaData, format); if (exif == null && xmp == null && iptc == null) { return(null); } BitmapMetadata jpegMetaData = new BitmapMetadata("jpg"); if (exif != null) { jpegMetaData.SetQuery("/app1/ifd/exif", new BitmapMetadata("exif")); foreach (var tag in exif) { object value = exif.GetQuery(tag); BitmapMetadata exifSub = value as BitmapMetadata; if (exifSub != null) { string baseQuery = "/app1/ifd/exif" + tag; CopySubIFDRecursive(ref jpegMetaData, exifSub, baseQuery); } else { jpegMetaData.SetQuery("/app1/ifd/exif" + tag, value); } } } if (xmp != null) { jpegMetaData.SetQuery("/xmp", new BitmapMetadata("xmp")); foreach (var tag in xmp) { object value = xmp.GetQuery(tag); BitmapMetadata xmpSub = value as BitmapMetadata; if (xmpSub != null) { CopySubIFDRecursive(ref jpegMetaData, xmpSub, "/xmp" + tag); } else { jpegMetaData.SetQuery("/xmp" + tag, value); } } } if (iptc != null) { jpegMetaData.SetQuery("/app13/irb/8bimiptc/iptc", new BitmapMetadata("iptc")); foreach (var tag in iptc) { object value = iptc.GetQuery(tag); BitmapMetadata iptcSub = value as BitmapMetadata; if (iptcSub != null) { CopySubIFDRecursive(ref jpegMetaData, iptcSub, "/app13/irb/8bimiptc/iptc" + tag); } else { jpegMetaData.SetQuery("/app13/irb/8bimiptc/iptc" + tag, value); } } } return(jpegMetaData); }
public void Set(int propId, object value) { string query = Query(propId); fNewMetadata.SetQuery(query, value); }
/// <summary> /// Converts the XMP meta data to TIFF format. /// </summary> /// <param name="metaData">The meta data to convert.</param> /// <param name="format">The format of the meta data.</param> /// <returns>The converted meta data or null.</returns> private static BitmapMetadata ConvertXMPMetaData(BitmapMetadata metaData, string format) { BitmapMetadata xmpData = null; try { if (format == "png") { BitmapMetadata textChunk = metaData.GetQuery("/iTXt") as BitmapMetadata; if (textChunk != null) { string keyWord = textChunk.GetQuery("/Keyword") as string; if (keyWord == "XML:com.adobe.xmp") { string textEntry = textChunk.GetQuery("/TextEntry") as string; if (!string.IsNullOrEmpty(textEntry)) { xmpData = LoadPNGMetaData(textEntry); } } } } else if (format == "jpg") { xmpData = metaData.GetQuery("/xmp") as BitmapMetadata; } else { try { xmpData = metaData.GetQuery("/ifd/xmp") as BitmapMetadata; } catch (IOException) { // WINCODEC_ERR_INVALIDQUERYREQUEST } if (xmpData == null) { // Some codecs may store the XMP data outside of the IFD block. xmpData = metaData.GetQuery("/xmp") as BitmapMetadata; } } } catch (IOException) { // WINCODEC_ERR_INVALIDQUERYREQUEST } // Return null if the XMP block does not contain any data. if ((xmpData == null) || !xmpData.Any()) { return(null); } BitmapMetadata tiffMetaData = new BitmapMetadata("tiff"); tiffMetaData.SetQuery("/ifd/xmp", new BitmapMetadata("xmp")); foreach (var tag in xmpData) { object value = xmpData.GetQuery(tag); BitmapMetadata xmpSub = value as BitmapMetadata; if (xmpSub != null) { CopySubBlockRecursive(ref tiffMetaData, xmpSub, "/ifd/xmp" + tag); } else { tiffMetaData.SetQuery("/ifd/xmp" + tag, value); } } return(tiffMetaData); }
/// <summary> /// Converts the EXIF meta data to JPEG format. /// </summary> /// <param name="metaData">The meta data to convert.</param> /// <returns>The converted meta data or null.</returns> private static BitmapMetadata ConvertEXIFMetaData(BitmapMetadata metaData) { BitmapMetadata exifData = null; try { exifData = metaData.GetQuery("/ifd/exif") as BitmapMetadata; } catch (IOException) { // WINCODEC_ERR_INVALIDQUERYREQUEST } // Return null if the EXIF block does not contain any data. if ((exifData == null) || !exifData.Any()) { return(null); } BitmapMetadata jpegMetaData = new BitmapMetadata("jpg"); jpegMetaData.SetQuery("/app1/ifd/exif", new BitmapMetadata("exif")); foreach (var tag in exifData) { object value = exifData.GetQuery(tag); BitmapMetadata exifSub = value as BitmapMetadata; if (exifSub != null) { CopySubBlockRecursive(ref jpegMetaData, exifSub, "/app1/ifd/exif" + tag); } else { jpegMetaData.SetQuery("/app1/ifd/exif" + tag, value); } } // Set the fields that are relevant for EXIF. try { if (!string.IsNullOrEmpty(metaData.ApplicationName)) { jpegMetaData.ApplicationName = metaData.ApplicationName; } if (!string.IsNullOrEmpty(metaData.CameraManufacturer)) { jpegMetaData.CameraManufacturer = metaData.CameraManufacturer; } if (!string.IsNullOrEmpty(metaData.CameraModel)) { jpegMetaData.CameraModel = metaData.CameraModel; } } catch (NotSupportedException) { } return(jpegMetaData); }
public static UInt16 RotateImageViaTranscoding(string filename, UInt16 prevOrient) { UInt16 orient = 1; orient = (UInt16)GetNextRotationOrientation(prevOrient); // get new rotation // This only works for jpg photos if (!filename.EndsWith("jpg")) { Console.WriteLine("The file you passed in is not a JPEG."); throw new ArgumentException("The file you passed in is not a JPEG:\n " + filename, "filename"); } // This code is based on http://blogs.msdn.com/b/rwlodarc/archive/2007/07/18/using-wpf-s-inplacebitmapmetadatawriter.aspx BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile; string outputTempFile = filename + "_out.jpg"; using (Stream originalFile = File.Open(filename, FileMode.Open, FileAccess.ReadWrite)) { // This method uses a lossless transcode operation and stores metadata changes in a temp file before copying them // back to the original file BitmapDecoder original = BitmapDecoder.Create(originalFile, createOptions, BitmapCacheOption.None); JpegBitmapEncoder output = new JpegBitmapEncoder(); // If you're just interested in doing a lossless transcode without adding metadata, just do this: //output.Frames = original.Frames; // If you want to add metadata to the image (or could use the InPlaceBitmapMetadataWriter with added padding) if (original.Frames[0] != null && original.Frames[0].Metadata != null) { // The BitmapMetadata object is frozen. So, you need to clone the BitmapMetadata and then // set the padding on it. Lastly, you need to create a "new" frame with the updated metadata. BitmapMetadata metadata = original.Frames[0].Metadata.Clone() as BitmapMetadata; // Of the metadata handlers that we ship in WIC, padding can only exist in IFD, EXIF, and XMP. // Third parties implementing their own metadata handler may wish to support IWICFastMetadataEncoder // and hence support padding as well. /* * metadata.SetQuery("/app1/ifd/PaddingSchema:Padding", paddingAmount); * metadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", paddingAmount); * metadata.SetQuery("/xmp/PaddingSchema:Padding", paddingAmount); * * // Since you're already adding metadata now, you can go ahead and add metadata up front. * metadata.SetQuery("/app1/ifd/{uint=897}", "hello there"); * metadata.SetQuery("/app1/ifd/{uint=898}", "this is a test"); * metadata.Title = "This is a title"; */ if (!metadata.ContainsQuery("/app1")) { metadata.SetQuery("/app1", new BitmapMetadata("app1")); } if (!metadata.ContainsQuery("/app1/{ushort=0}")) { metadata.SetQuery("/app1/{ushort=0}", new BitmapMetadata("ifd")); } metadata.SetQuery("/app1/{ushort=0}/{ushort=274}", orient); //set next rotation // Create a new frame identical to the one from the original image, except the metadata changes. // Essentially we want to keep this as close as possible to: // output.Frames = original.Frames; output.Frames.Add(BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, metadata, original.Frames[0].ColorContexts)); } using (Stream outputFile = File.Open(outputTempFile, FileMode.Create, FileAccess.ReadWrite)) { output.Save(outputFile); } } // Delete the original and replace it with the temp output file File.Delete(filename); File.Move(outputTempFile, filename); return(orient); }
public bool WriteMetadata() { FileInfo original = new FileInfo(FilePath); FileInfo newFile = new FileInfo(FilePath + "_newFile"); bool bSuccess = false; const BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile; using (Stream originalFileStream = File.Open(original.FullName, FileMode.Open, FileAccess.Read)) { BitmapDecoder decoder = BitmapDecoder.Create(originalFileStream, createOptions, BitmapCacheOption.None); if (decoder.CodecInfo != null && decoder.CodecInfo.FileExtensions.Contains("jpg") && decoder.Frames[0] != null) { BitmapMetadata metadata = decoder.Frames[0].Metadata == null ? new BitmapMetadata("jpg") : decoder.Frames[0].Metadata.Clone() as BitmapMetadata; if (metadata != null) { //People const string microsoftRegionInfo = @"/xmp/MP:RegionInfo"; const string microsoftRegions = @"/xmp/MP:RegionInfo/MPRI:Regions"; const string microsoftPersonDisplayName = @"/MPReg:PersonDisplayName"; int peopleIdx = -1; List<string> addedPeople = new List<string>(); //New metadata just for People BitmapMetadata people = new BitmapMetadata("jpg"); people.SetQuery(microsoftRegionInfo, new BitmapMetadata("xmpstruct")); people.SetQuery(microsoftRegions, new BitmapMetadata("xmpbag")); //Adding existing people BitmapMetadata existingPeople = metadata.GetQuery(microsoftRegions) as BitmapMetadata; if (existingPeople != null) { foreach (string idx in existingPeople) { var existingPerson = metadata.GetQuery(microsoftRegions + idx) as BitmapMetadata; var personDisplayName = existingPerson?.GetQuery(microsoftPersonDisplayName); if (personDisplayName == null) continue; if (!People.Any(p => p.Title.Equals(personDisplayName.ToString()))) continue; addedPeople.Add(personDisplayName.ToString()); peopleIdx++; people.SetQuery($"{microsoftRegions}/{{ulong={peopleIdx}}}", existingPerson); } } //Adding new people foreach (Person person in People.Where(p => !addedPeople.Any(ap => ap.Equals(p.Title)))) { peopleIdx++; people.SetQuery($"{microsoftRegions}/{{ulong={peopleIdx}}}", new BitmapMetadata("xmpstruct")); people.SetQuery($"{microsoftRegions}/{{ulong={peopleIdx}}}" + microsoftPersonDisplayName, person.Title); } //Writing all people to MediaItem metadata var allPeople = people.GetQuery(microsoftRegionInfo); if (allPeople != null) metadata.SetQuery(microsoftRegionInfo, allPeople); metadata.Rating = Rating; metadata.Comment = Comment ?? string.Empty; metadata.Keywords = new ReadOnlyCollection<string>(Keywords.Select(k => k.FullPath).ToList()); JpegBitmapEncoder encoder = new JpegBitmapEncoder { QualityLevel = Settings.Default.JpegQualityLevel }; encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0], decoder.Frames[0].Thumbnail, metadata, decoder.Frames[0].ColorContexts)); try { using (Stream newFileStream = File.Open(newFile.FullName, FileMode.Create, FileAccess.ReadWrite)) { encoder.Save(newFileStream); } bSuccess = true; } catch (Exception) { bSuccess = false; } } } } if (bSuccess) { newFile.CreationTime = original.CreationTime; original.Delete(); newFile.MoveTo(original.FullName); } return bSuccess; }
private void LoadImage(string filename) { FullScreenImage.RenderTransform = null; FullScreenImage.Visibility = Visibility.Visible; FullScreenMedia.Visibility = Visibility.Collapsed; try { using (FileStream imgStream = File.Open(filename, FileMode.Open, FileAccess.ReadWrite)) { if (Path.GetExtension(filename).ToLower() == ".jpg") // load exif only for jpg { StringBuilder info = new StringBuilder(); //var decoder = new JpegBitmapDecoder(imgStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); //var decoder = new JpegBitmapDecoder(imgStream, BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.OnLoad); BitmapDecoder decoder = BitmapDecoder.Create(imgStream, BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.OnLoad); var bitmapFrame = decoder.Frames[0]; // create an encoder for the output file JpegBitmapEncoder output = new JpegBitmapEncoder(); if (bitmapFrame != null) { BitmapFrame frameCopy = (BitmapFrame)bitmapFrame.Clone(); BitmapMetadata metaData = (BitmapMetadata)bitmapFrame.Metadata.Clone(); info.AppendLine(filename + "\n" + (int)bitmapFrame.Width + "x" + (int)bitmapFrame.Height); if (metaData != null) { if (!String.IsNullOrWhiteSpace(metaData.DateTaken)) { info.AppendLine("Date taken: " + metaData.DateTaken); } if (!String.IsNullOrWhiteSpace(metaData.Title)) { info.AppendLine("Title: " + metaData.Title); } if (!String.IsNullOrWhiteSpace(metaData.Subject)) { info.AppendLine("Subject: " + metaData.Subject); } if (!String.IsNullOrWhiteSpace(metaData.Comment)) { info.AppendLine("User comment: " + metaData.Comment); } Console.WriteLine("Begin medatdata dump *******************************************"); //PrintMetadata(decoder.Frames[0].Metadata, string.Empty); Console.WriteLine("End medatdata dump *******************************************"); String xmpSubject = (String)metaData.GetQuery("/xmp/dc:subject/{ulong=0}"); UInt16 orient = 1; System.Drawing.RotateFlipType fType = System.Drawing.RotateFlipType.RotateNoneFlipNone; if (metaData.ContainsQuery(@"/app1/{ushort=0}/{ushort=274}")) { orient = (UInt16)metaData.GetQuery(@"/app1/{ushort=0}/{ushort=274}"); //get rotation fType = GetRotateFlipTypeByExifOrientationData(orient); } if (imageRotationAngle == 90) { orient = (UInt16)GetNextRotationOrientation(orient); // get new rotation //create keys if we dont have it yet if (!metaData.ContainsQuery("/app1")) { metaData.SetQuery("/app1", new BitmapMetadata("app1")); } if (!metaData.ContainsQuery("/app1/{ushort=0}")) { metaData.SetQuery("/app1/{ushort=0}", new BitmapMetadata("ifd")); } metaData.SetQuery("/app1/{ushort=0}/{ushort=274}", orient); //set next rotation fType = GetRotateFlipTypeByExifOrientationData(orient); var enc = new JpegBitmapEncoder(); //enc.Frames.Add(BitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metaData, bitmapFrame.ColorContexts)); enc.Frames.Add(BitmapFrame.Create(frameCopy, frameCopy.Thumbnail, metaData, frameCopy.ColorContexts)); output.Frames.Add(BitmapFrame.Create(frameCopy, frameCopy.Thumbnail, metaData, null)); imgStream.Seek(0, SeekOrigin.Begin); //imgStream.SetLength(0); // clear all data enc.Save(imgStream); // finally, save the new file over the old file using (Stream outputFile = File.Open(filename + "_out.jpg", FileMode.Create, FileAccess.Write)) { output.Save(outputFile); } } imageRotationAngle = GetBitmapRotationAngleByRotationFlipType(fType); } } Overlay.Text = info.ToString(); imgStream.Flush(); imgStream.Close(); } else //if (Path.GetExtension(filename).ToLower() == ".jpg") { if (imageRotationAngle == 90) { //rotate other types of image using Image class using (Image imgForRotation = Image.FromStream(imgStream, false, false)) { Overlay.Text = filename + "\n" + imgForRotation.Width + "x" + imgForRotation.Height; imgForRotation.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone); imgStream.Seek(0, SeekOrigin.Begin); switch (Path.GetExtension(filename).ToLower()) { case ".png": imgForRotation.Save(imgStream, ImageFormat.Png); break; case ".bmp": imgForRotation.Save(imgStream, ImageFormat.Bmp); break; case ".gif": imgForRotation.Save(imgStream, ImageFormat.Gif); break; } } imgStream.Flush(); imgStream.Close(); imageRotationAngle = 0; // because we already have rotated image } else { Overlay.Text = ""; // we will set it bellow } } } } catch { Overlay.Text = ""; } try { using ( var imgStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read)) { var img = new BitmapImage(); img.BeginInit(); img.CacheOption = BitmapCacheOption.OnLoad; img.StreamSource = imgStream; // load image from stream instead of file img.EndInit(); // Rotate Image if necessary TransformedBitmap transformBmp = new TransformedBitmap(); transformBmp.BeginInit(); transformBmp.Source = img; RotateTransform transform = new RotateTransform(imageRotationAngle); transformBmp.Transform = transform; transformBmp.EndInit(); FullScreenImage.Source = transformBmp; // Initialize rotation variable for next image imageRotationAngle = 0; imageTimer.Start(); //if we failed to get exif data set some basic info if (String.IsNullOrWhiteSpace(Overlay.Text)) { Overlay.Text = filename + "\n" + img.Width + "x" + img.Height; } } } catch { FullScreenImage.Source = null; ShowError("Can not load " + filename + " ! Screensaver paused, press P to unpause."); } }
private void SetOrientationMetadata(BitmapMetadata bitmapMetadata, MetadataItemName metaName, MetaPersistAction persistAction) { switch (persistAction) { case MetaPersistAction.Delete: bitmapMetadata.RemoveQuery(UpdatableMetaItems[metaName]); break; case MetaPersistAction.Save: IGalleryObjectMetadataItem orientationMeta; if (GalleryObject.MetadataItems.TryGetMetadataItem(metaName, out orientationMeta)) { ushort orientationRaw; if (UInt16.TryParse(orientationMeta.RawValue, out orientationRaw) && MetadataEnumHelper.IsValidOrientation((Orientation)orientationRaw)) { bitmapMetadata.SetQuery(UpdatableMetaItems[metaName], orientationRaw); } } break; default: throw new InvalidEnumArgumentException(String.Format(CultureInfo.CurrentCulture, "This function is not designed to handle the enumeration value {0}. The function must be updated.", persistAction)); } }
private void BlankMetaInfo(string query, BitmapMetadata metaData) { object obj = metaData.GetQuery(query); if (obj != null) { if (obj is string) metaData.SetQuery(query, string.Empty); else { ulong dummy; if (ulong.TryParse(obj.ToString(), out dummy)) { metaData.SetQuery(query, 0); } } } }
/// <summary> /// Converts the meta-data to TIFF format. /// </summary> /// <param name="metadata">The meta data.</param> /// <returns>The converted meta data or null</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="metadata"/> is null. /// </exception> private static BitmapMetadata ConvertMetadataToTIFF(BitmapMetadata metadata) { if (metadata == null) { throw new ArgumentNullException(nameof(metadata)); } string format = string.Empty; try { format = metadata.Format; // Some WIC codecs do not implement the format property. } catch (ArgumentException) { } catch (NotSupportedException) { } if (format != "tiff") { BitmapMetadata exif = GetEXIFMetadata(metadata, format); BitmapMetadata xmp = GetXMPMetadata(metadata, format); BitmapMetadata iptc = GetIPTCMetadata(metadata, format); if (exif == null && xmp == null && iptc == null) { return(null); } BitmapMetadata tiffMetadata = new BitmapMetadata("tiff"); if (exif != null) { tiffMetadata.SetQuery("/ifd/exif", new BitmapMetadata("exif")); foreach (string tag in exif) { object value = exif.GetQuery(tag); if (value is BitmapMetadata exifSub) { CopySubIFDRecursive(ref tiffMetadata, exifSub, "/ifd/exif" + tag); } else { tiffMetadata.SetQuery("/ifd/exif" + tag, value); } } } if (xmp != null) { tiffMetadata.SetQuery("/ifd/xmp", new BitmapMetadata("xmp")); foreach (string tag in xmp) { object value = xmp.GetQuery(tag); if (value is BitmapMetadata xmpSub) { CopySubIFDRecursive(ref tiffMetadata, xmpSub, "/ifd/xmp" + tag); } else { tiffMetadata.SetQuery("/ifd/xmp" + tag, value); } } } if (iptc != null) { tiffMetadata.SetQuery("/ifd/iptc", new BitmapMetadata("iptc")); foreach (string tag in iptc) { object value = iptc.GetQuery(tag); if (value is BitmapMetadata iptcSub) { CopySubIFDRecursive(ref tiffMetadata, iptcSub, "/ifd/iptc" + tag); } else { tiffMetadata.SetQuery("/ifd/iptc" + tag, value); } } } return(tiffMetadata); } return(metadata); }
/// <summary> /// Method to apply meta data in the jpg file /// </summary> /// <param name="inputFileName">input file name</param> /// <param name="outputFileName">output file name</param> /// <param name="metaDataCollection">Metadata collection</param> /// <returns></returns> public MetadataResult ApplyMetaData(string inputFileName, string outputFileName, List <DocumentData> metaDataCollection) { MetadataResult retDataCol = new MetadataResult(); if (metaDataCollection == null) { retDataCol.Status = "Error"; retDataCol.Message = "There has to be at least 1 metadata field that needs to be applied to the assest"; } try { using (FileStream fileStream = File.Open(inputFileName, FileMode.Open)) { //Creating the bitmat decoder from the input file streaam BitmapDecoder decoder = PngBitmapDecoder.Create(fileStream, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.Default); BitmapMetadata md = new BitmapMetadata("png"); //Creating the frame with the meta data BitmapFrame frame = BitmapFrame.Create(decoder.Frames[0], decoder.Frames[0].Thumbnail, md, decoder.Frames[0].ColorContexts); PngBitmapEncoder encoder = new PngBitmapEncoder(); // BitmapMetadata md = new BitmapMetadata("png"); encoder.Frames.Add(frame); int ctr = 0; foreach (DocumentData documentData in metaDataCollection) { if (ctr == 0) { //Adding the meta data // md.SetQuery(@"/Text/" + key, metaDataCollection[key]); md.SetQuery("/iTXt/Keyword", documentData.Key.ToCharArray()); // need to convert using ToCharArray as internal representation is based on the LPSTR C type md.SetQuery("/iTXt/TextEntry", documentData.Text); } else { md.SetQuery("/[" + ctr + "]iTXt/" + "Keyword", documentData.Key.ToCharArray()); // need to convert using ToCharArray as internal representation is based on the LPSTR C type md.SetQuery("/[" + ctr + "]iTXt/" + "TextEntry", documentData.Text); } ctr++; } // encoder.Frames.Add(frame); //after assigning the meta data saving to another file using (FileStream of = File.Open(outputFileName, FileMode.Create, FileAccess.Write)) { encoder.Save(of); of.Close(); } } retDataCol.Status = "Success"; retDataCol.Message = "Metadata applied successfully."; } catch (Exception ex) { retDataCol.Status = "Error"; retDataCol.Message = ex.ToString(); //Logger.LogError("JPEGImageDocument", "ApplyMetaData", inputFileName, outputFileName, ex); } return(retDataCol); }
private static BitmapMetadata ConvertMetadataToWMPhoto(BitmapMetadata metadata, string format) { BitmapMetadata exif = GetEXIFMetadata(metadata, format); BitmapMetadata xmp = GetXMPMetadata(metadata, format); BitmapMetadata iptc = GetIPTCMetadata(metadata, format); if (exif == null && xmp == null && iptc == null) { return(null); } BitmapMetadata wmpMetadata = new BitmapMetadata("wmphoto"); if (exif != null) { wmpMetadata.SetQuery("/ifd/exif", new BitmapMetadata("exif")); foreach (string tag in exif) { object value = exif.GetQuery(tag); if (value is BitmapMetadata exifSub) { CopySubIFDRecursive(ref wmpMetadata, exifSub, "/ifd/exif" + tag); } else { wmpMetadata.SetQuery("/ifd/exif" + tag, value); } } } if (xmp != null) { wmpMetadata.SetQuery("/ifd/xmp", new BitmapMetadata("xmp")); foreach (string tag in xmp) { object value = xmp.GetQuery(tag); if (value is BitmapMetadata xmpSub) { CopySubIFDRecursive(ref wmpMetadata, xmpSub, "/ifd/xmp" + tag); } else { wmpMetadata.SetQuery("/ifd/xmp" + tag, value); } } } if (iptc != null) { wmpMetadata.SetQuery("/ifd/iptc", new BitmapMetadata("iptc")); foreach (string tag in iptc) { object value = iptc.GetQuery(tag); if (value is BitmapMetadata iptcSub) { CopySubIFDRecursive(ref wmpMetadata, iptcSub, "/ifd/iptc" + tag); } else { wmpMetadata.SetQuery("/ifd/iptc" + tag, value); } } } return(wmpMetadata); }
private void writeMetatadata(string query, object data) { metadata.SetQuery(query, data); }