Reputation: 1321
NOTE: this is UWP-specific, please do not reply with what works in WPF, WinForms, C++, etc. we have already looked at these.
Trying to encode iTXt
metadata block into a PNG in UWP/WIC but having an issue with the Keyword
field. Encoding metadata with other encoders works fine (if you know the "rules" of each encoder).
"Vanilla" WIC documentation says that Keyword
has type VT_LPSTR
. A well-referenced example (not for UWP) states to pass the "char array" via String.toCharArray
but this does not work in UWP, and generates ArgumentException: Value does not fall within the expected range.
when trying to set the BitmapProperties.SetPropertiesAsync
.
Trying to encode a "regular" tEXt
metadata block works just fine, because the keyword is part of the "path" e.g. "/tEXt/{str=Software}" for the "Software" tag.
pset.Add("/[*]tEXt/{str=Author}", new BitmapTypedValue("The Author", Windows.Foundation.PropertyType.String));
As a bonus complication, the [*]
is required when adding multiple blocks (e.g. Author and Description), otherwise only one comes out!
However for an iTXt
block (at least) two such values are required: the Keyword
and the TextEntry
.
What also failed for iTXt
is using the "key" syntax so "/[*]iTXt/{str=Software}/TextEntry" results in Exception: The codec is in the wrong state
so this is clearly not intended use.
This applies to any other "structured" metadata items in other formats. This does not appear to be an issue for the "media policy" based metadata; it appears already "destructured" to facilitate BitmapTypeValue
for everything.
Can anyone provide insight into how to make this work (in UWP C#)?
In the meantime, figured out we need to pass in an "aggregate" object instead of doing it as indicated previously (deleted). This means passing in a value of Inspectable
.
When receiving decoded metadata from e.g. a JPG with XMP in it, these appear as Windows.Graphics.Imaging.BitmapPropertiesView
instances.
This makes sense; as commenter pointed out, the data is "structured".
However, there appears to be no way to construct an instance of BitmapPropertyView
and set that as the BitmapTypedValue
representing an aggregate metadata value. Looking at the other relevant classes, there appear to be no "moves" to get from something with a constructor, to BitmapPropertiesView
.
We have tried this incantation with no luck; produces a "cast" exception (which makes sense considering).
var txt = new BitmapPropertySet();
txt.Add("Keyword", new BitmapTypedValue("Software", Windows.Foundation.PropertyType.String));
txt.Add("CompressionFlag", new BitmapTypedValue(1, Windows.Foundation.PropertyType.UInt8));
txt.Add("TextEntry", su);
pset.Add("/[*]iTXt", new BitmapTypedValue(txt, Windows.Foundation.PropertyType.Inspectable));
Obviously BitmapPropertySet
cannot function as the "container" but then what class in the UWP can be used here?
Upvotes: 0
Views: 130