title: Write metadata to both jpg and png
body: <p>I need to add a metadata tag (description) to uploaded images.</p>
  
  <p>I have found out this answer: <a href="https://stackoverflow.com/a/1764913/6776">https://stackoverflow.com/a/1764913/6776</a> which works great for JPG files, but not for PNG.</p>
  
  <pre><code>private string Tag = "test meta data";
  
  private static Stream TagImage(Stream input, string type)
  {
      bool isJpg = type.EndsWith("jpg", StringComparison.InvariantCultureIgnoreCase) || type.EndsWith("jpeg", StringComparison.InvariantCultureIgnoreCase);
      bool isPng = type.EndsWith("png", StringComparison.InvariantCultureIgnoreCase);
  
      BitmapDecoder decoder = null;
  
      if (isJpg)
      {
          decoder = new JpegBitmapDecoder(input, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
      }
      else if (isPng)
      {
          decoder = new PngBitmapDecoder(input, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
      }
      else
      {
          return input;
      }
  
      // modify the metadata
      BitmapFrame bitmapFrame = decoder.Frames[0];
      BitmapMetadata metaData = (BitmapMetadata)bitmapFrame.Metadata.Clone();
      metaData.Subject = Tag;
      metaData.Comment = Tag;
      metaData.Title = Tag;
  
      // get an encoder to create a new jpg file with the new metadata.      
      BitmapEncoder encoder = null;
      if (isJpg)
      {
          encoder = new JpegBitmapEncoder();
      }
      else if (isPng)
      {
          encoder = new PngBitmapEncoder();
      }
  
      encoder.Frames.Add(BitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metaData, bitmapFrame.ColorContexts));
  
      // Save the new image 
      Stream output = new MemoryStream();
      encoder.Save(output);
  
      output.Seek(0, SeekOrigin.Begin);
  
      return output;
  }
  </code></pre>
  
  <p>It works great when I upload a jpg, but with a png, at the <code>metaData.Subject = Tag</code> line, it throws a <code>System.NotSupportedException</code> (this codec does not support the specified property).</p>
  
  <h1>Update</h1>
  
  <p>It seems I have to use a different method based on the image format:</p>
  
  <pre><code>if (isJpg)
  {
      metaData.SetQuery("/app1/ifd/exif:{uint=270}", Tag);
  }
  else
  {
      metaData.SetQuery("/tEXt/{str=Description}", Tag);
  }
  </code></pre>
  
  <p>Based on <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ee719904%28v=vs.85%29.aspx?f=255&amp;MSPPError=-2147217396" rel="nofollow noreferrer">the available formats' queries</a> the first should work for both formats. The second doesn't really work either (it creates the metadata in the image but does not save its value).</p>
  
  <p>If I try to use the first method (<code>/app1/ifd/exif</code>) for PNG, at the <code>encoder.Save</code> line I get a not supported exception, "no imaging component suitable".</p>