locked
Cannot set JPEG metadata using BitmapMetadata RRS feed

  • Question

  • I am trying to copy all and modify metadata some EXIF fields from a JPEG file using the code below:

    public void CopyAndSetMetadata(string sourceFile, string destFile, string sXPTitle, string sXPSubject, string sXPComment, int Width, int Height) { uint paddingAmount = 4096; / using (Stream sourceStream = System.IO.File.Open(sourceFile, FileMode.Open, FileAccess.Read)) { BitmapDecoder sourceDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.None); // Check source is has valid frames if (sourceDecoder.Frames[0] != null && sourceDecoder.Frames[0].Metadata != null) { // Get a clone copy of the metadata BitmapMetadata sourceMetadata = sourceDecoder.Frames[0].Metadata.Clone() as BitmapMetadata; // Open the temp file // modify values sourceMetadata.SetQuery("/app1/ifd/PaddingSchema:Padding", paddingAmount); sourceMetadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", paddingAmount); sourceMetadata.SetQuery("/xmp/PaddingSchema:Padding", paddingAmount); sourceMetadata.SetQuery("/app1/ifd/exif/{uint=0x100}",Width); // Image Width int 32 sourceMetadata.SetQuery("/app1/ifd/exif/{uint=0x101}", Height); // Image Height int32 sourceMetadata.SetQuery("/app1/ifd/exif/{uint=0x9c9b}", sXPTitle); //XPTitle int 16u sourceMetadata.SetQuery("/app1/ifd/exif/{uint=0x9c9f}", sXPSubject); // XPSubject int 16u sourceMetadata.SetQuery("/app1/ifd/exif/{uint=0x9c9c}", sXPComment); // XPComment int 16u }

    ... code to set metadata in Destfile } }


    However, I get a Type Mismatch error when any of the SetQuery call are made after adding the padding. For the first call to set ImageWidth, i have tried casting the input int parameter Width to uint, long and string and also creating a 2-Byte array. I have alalso tried casting sXPTitle to a Byte array without success. What types does SetQuery expect for its second argument for the didifferent EXIF tags? (I have added the types as shown in the EXIF tags list on the Exiftool web page  https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html as comments.

    • Moved by CoolDadTx Saturday, August 18, 2018 7:15 AM WPF related
    Saturday, August 18, 2018 2:33 AM

Answers

  • Found the solution - the type mismatch was caused by setting the uint to a Hex value. Having fixed that, the second problem was that values were not getting updated. This was a syntax error in SetQuery. The EXIF fields XP Subject, XPTitle  XPComment have to be set as Byte arrays. The code below sets values, in all the fields including Chinese characters in strings using Unicode:

    public void CopyAndSetMetadata(string sourceFile, string destinationFile,string sXPTitle, string sXPSubject, 
                string sXPComment, int Width, int Height,bool bShowErrors = false)
    {
            uint paddingAmount = 2048;
                  
    	using (Stream sourceStream = System.IO.File.Open(sourceFile, FileMode.Open, FileAccess.Read))
    	{
    		BitmapDecoder sourceDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.None);       // Check source is has valid frames
    		if (sourceDecoder.Frames[0] != null && sourceDecoder.Frames[0].Metadata != null)
    		{
    			// Get a clone copy of the metadata
    			BitmapMetadata sourceMetadata = sourceDecoder.Frames[0].Metadata.Clone() as BitmapMetadata;          // Open the temp file
    			// modify values
    			sourceMetadata.SetQuery("/app1/ifd/PaddingSchema:Padding", paddingAmount);  
    			sourceMetadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", paddingAmount);  
    			sourceMetadata.SetQuery("/xmp/PaddingSchema:Padding", paddingAmount);
    
    			sourceMetadata.SetQuery("/app1/ifd/exif:{uint=256}",Width); // Image Width int 32
    			sourceMetadata.SetQuery("/app1/ifd/exif:{uint=257}", Height); // Image Height int32
    
    		   Encoding _Encoding = Encoding.UTF8;
    			sourceMetadata.SetQuery("/app1/ifd/exif:{uint=40091}",  _Encoding.GetBytes(sXPTitle + '\0')); //XPTitle  int 16u
    			sourceMetadata.SetQuery("/app1/ifd/exif:{uint=40095}", _Encoding.GetBytes(sXPSubject+ '\0')); // XPSubject int 16u
    			sourceMetadata.SetQuery("/app1/ifd/exif:{uint=40092}", _Encoding.GetBytes(sXPComment + '\0')); // XPComment int 16u
    		}
    	}
    }


    • Marked as answer by Simon Kravis Sunday, August 19, 2018 12:51 AM
    • Edited by Simon Kravis Sunday, August 19, 2018 12:53 AM
    Sunday, August 19, 2018 12:51 AM