ciao,
pietro09 ha scritto:
ps. se non volessi copiare un metadato ma crearlo ex novo, si potrebbe fare?
Sì, è possibile, anche se la API pone degli ostacoli.
Il problema è che la classe PropertyItem non ha un costruttore pubblico, quindi non potresti crearne una nuova istanza. La
documentazione su MSDN lo giustifica così:
A PropertyItem is not intended to be used as a stand-alone object.
[...]
the PropertyItem class does not have a defined Public constructor, and you cannot create an instance of a PropertyItem object.
Non riesco a comprenderne il motivo dato che ci viene messo a disposizione un metodo SetPropertyItem. Oltretutto, la classe PropertyItem non ha alcun comportamento interno: il suo costruttore è vuoto e nel complesso ha l'aspetto di una semplice struttura dati.
Può darsi che questa API non sia ancora abbastanza matura e
user-friendly per un uso pubblico. Comunque noi non ci badiamo, penso che in questo specifico caso sia legittimo "barare" e usare la reflection per arrivare al costruttore interno. Tanto potremmo comunque giungere ad una soluzione prendendo in prestito l'istanza di un PropertyItem da un altro oggetto Bitmap.
Detto questo, mi creerei un'istanza così:
var nuovoPropItem = (PropertyItem)typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null).Invoke(null);
Adesso dobbiamo capire come valorizzare le quattro proprietà (
documentate qui) del PropertyItem che abbiamo appena creato.
Ipotizziamo di voler aggiungere una
descrizione alla foto. Nella
documentazione si scopre che questa proprietà Exif è rappresentata dal codice 0x010E. Impostiamo il suo Id di conseguenza.
nuovoPropItem.Id = 0x010E;
Ora, la descrizione è una proprietà di tipo
PropertyTagTypeASCII. MSDN non ci dice il codice corrispondente ma lo troviamo in
questa pagina.
Adesso andiamo ad impostare il contenuto vero e proprio della descrizione. Qui per non fare errori bisogna leggere attentamente la documentazione, eventualmente integrandola con la
specifica Exif. Ogni proprietà Exif ha le sue peculiarità. Per la descrizione si legge:
Null-terminated character string that specifies the title of the image.
Dunque prepariamo una stringa terminata da null e la convertiamo in array di bytes, perché questo è il tipo di dato che il PropertyItem si aspetta di ricevere.
var descrizione = System.Text.Encoding.UTF8.GetBytes("Visita alla città d'arte" + "\0");
nuovoPropItem.Value = descrizione;
Infine dobbiamo indicare il numero di bytes occupato dal nostro testo. La documentazione riferisce:
Length of the string including the NULL terminator
Benissimo, allora ci basta prendere in considerazione la lunghezza dell'array di bytes, perché quello già includeva il terminatore null.
nuovoPropItem.Len = descrizione.Length;
Adesso non resta che impostare il PropertyItem sull'immagine.
immagine.SetPropertyItem(nuovoPropItem);
Ricapitolando, il codice che abbiamo scritto per impostare un nuovo PropertyItem su una Bitmap è il seguente.
var nuovoPropItem = (PropertyItem)typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null).Invoke(null);
nuovoPropItem.Id = 0x010E;
nuovoPropItem.Type = 2;
var descrizione = System.Text.Encoding.UTF8.GetBytes("Visita alla città d'arte" + "\0");
nuovoPropItem.Value = descrizione;
nuovoPropItem.Len = descrizione.Length;
immagine.SetPropertyItem(nuovoPropItem);
ciao,
Moreno
Modificato da BrightSoul il 27 novembre 2013 15.14 -