0 Replies - 5608 Views - Last Post: 01 March 2009 - 05:26 PM Rate Topic: -----

#1 StCroixSkipper   User is offline

  • D.I.C Head
  • member icon

Reputation: 10
  • View blog
  • Posts: 121
  • Joined: 23-December 08

Using InPlaceBitmapMetaDataWriter function

Post icon  Posted 01 March 2009 - 05:26 PM

I think the documentation for modifying the image metadata is confusing. Here is what I've discovered and some code that works with jpg files. I think you should be able to adapt it to other fields and other image file types. Good Luck

public ModifyJpgMetadata()   
{   
	//   
	// get the path to some jpg file   
	//   
	string jpegPath = "C:\\users\\scott\\Pictures\\sample\\xxx.jpg";   
	string jpegDirectory = Path.GetDirectoryName(jpegPath);   
	string jpegFileName = Path.GetFileNameWithoutExtension(jpegPath);   
	string jpegExtension = ".jpg";   
  
	BitmapDecoder decoder = null;   
	BitmapFrame bitmapFrame = null;   
	BitmapMetadata metadata = null;   
	if (File.Exists(jpegPath))   
	{   
		//   
		// load the jpg file with a JpegBitmapDecoder   
		//   
		using (Stream jpegStreamIn = File.Open(jpegPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))   
		{   
			decoder = new JpegBitmapDecoder(jpegStreamIn, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.onload);   
		}   
  
		bitmapFrame = decoder.Frames[0];   
		metadata = (BitmapMetadata)bitmapFrame.Metadata;   
  
		if (bitmapFrame != null)   
		{   
			//   
			// now get an InPlaceBitmapMetadataWriter, modify the metadata and try to save   
			//   
			InPlaceBitmapMetadataWriter writer = bitmapFrame.CreateInPlaceBitmapMetadataWriter();   
			writer.SetQuery("/app1/ifd/exif:{uint=306}", "2001:01:01 01:01:01");   
			if (!writer.TrySave() == true)   
			{   
				//   
				// the size of the metadata has been increased and we can't save it   
				//	
				uint padding = 2048;   
  
				BitmapMetadata metaData = (BitmapMetadata)bitmapFrame.Metadata.Clone();   
				if (metaData != null)   
				{   
					//   
					// Add padding   
					//   
					metaData.SetQuery("/app1/ifd/PaddingSchema:Padding", padding);   
					//   
					// modify the metadata   
					metaData.SetQuery("/app1/ifd/exif:{uint=36867}", "2003:03:03 03:04:03");   
					metaData.SetQuery("/app1/ifd/exif:{uint=306}", "2001:01:01 01:01:01");   
					metaData.SetQuery("/app1/ifd/exif:{uint=36868}", "2002:02:02 02:02:02");   
					//   
					// get an encoder to create a new jpg file with the addit'l metadata.   
					//   
					JpegBitmapEncoder encoder = new JpegBitmapEncoder();   
					encoder.Frames.Add(BitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metaData, bitmapFrame.ColorContexts));   
					string jpegNewFileName = Path.Combine(jpegDirectory, "JpegTemp.jpg");   
					using (Stream jpegStreamOut = File.Open(jpegNewFileName, FileMode.CreateNew, FileAccess.ReadWrite))   
					{   
						encoder.Save(jpegStreamOut);   
					}   
					//   
					// see if the metadata was really changed   
					//   
					using (Stream jpegStreamIn = File.Open(jpegNewFileName, FileMode.Open, FileAccess.ReadWrite))   
					{   
						decoder = new JpegBitmapDecoder(jpegStreamIn, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.onload);   
						BitmapFrame frame = decoder.Frames[0];   
						BitmapMetadata bmd = (BitmapMetadata)frame.Metadata;   
						string a1 = (string)bmd.GetQuery("/app1/ifd/exif:{uint=36867}");   
						string a2 = (string)bmd.GetQuery("/app1/ifd/exif:{uint=306}");   
						string a3 = (string)bmd.GetQuery("/app1/ifd/exif:{uint=36868}");   
					}   
				}   
			}   
		}   
	}   
}   
 

You can step through this code and look at a1, a2 and a3 to verify they have been changed.

Just a note:
The documentation shows code like this:
Stream pngStream = new System.IO.FileStream("smiley.png", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);   
PngBitmapDecoder pngDecoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);   
BitmapFrame pngFrame = pngDecoder.Frames[0];   
InPlaceBitmapMetadataWriter pngInplace = pngFrame.CreateInPlaceBitmapMetadataWriter();   
if (pngInplace.TrySave() == true)   
{ pngInplace.SetQuery("/Text/Description", "Have a nice day."); }   
pngStream.Close();



Which can't work because pngInplace.TrySave() always returns true. This makes sense because you haven't changed the metadata size.
The code should really look more like:
Stream pngStream = new System.IO.FileStream("smiley.png", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);   
PngBitmapDecoder pngDecoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);   
BitmapFrame pngFrame = pngDecoder.Frames[0];   
InPlaceBitmapMetadataWriter pngInplace = pngFrame.CreateInPlaceBitmapMetadataWriter();   
  
pngInplace.SetQuery("/Text/Description", "Have a nice day.");   
	
if (pngInplace.TrySave() == true)   
{	
   //   
   // add padding, change the metadata and save to a new file   
   //   
}   
pngStream.Close();  



Is This A Good Question/Topic? 0
  • +

Page 1 of 1