View Full Version : [C#]TagLib sharp: settare immagine album
Mattyfog
02-05-2010, 10:29
Ciao a tutti!
Sto usando la libreria TagLib sharp ma non capisco come settare l'immagine della copertina dell'album a partire da un oggetto Image.
Ho provato di tutto ma non ci riesco! Qualcuno sa qualcosa?
Ho cercato online senza risultati...
Mattyfog
02-05-2010, 16:30
forse sto risolvendo..
ditemi una cosa però..
Se io ho una variabile di tipo Image e volessi creare una variabile di tipo File che "contenga" (o meglio, che sia proprio) l'immagine contenuta nella variabile di tipo image come posso fare?
Mattyfog
04-05-2010, 20:56
vi prego sono le ultime cose per finire il programma...
è che non so come fare perchè il file non va scritto fisicamente sul disco ma deve essere solo una variabile!
wingman87
04-05-2010, 21:18
http://msdn.microsoft.com/en-us/library/9t4syfhh.aspx
Se ho capito bene il problema...
Mattyfog
05-05-2010, 12:48
non proprio, in pratica io ho:
File file;
Image immagine;
E, senza scrivere la variabile file sul disco, devo "scrivere" la variabile immagine nella variabile file.
Forse so come fare, ma non so come posso creare un FileStream che punti alla variabile file senza che essa venga scritta sul disco.
wingman87
05-05-2010, 12:59
Ci sono vari overload di save, anche questo che salva su uno stream generico:
http://msdn.microsoft.com/en-us/library/ms142147%28v=VS.100%29.aspx
Mattyfog
05-05-2010, 13:47
Si appunto questo lo so, non so come creare un FileStream che punti alla variabile file (che non corrisponde a un file scritto sul disco)
wingman87
05-05-2010, 14:59
E a cosa corrisponde?
Mattyfog
05-05-2010, 15:03
In che senso?
Io semplicemente non so come creare un FileStream che mi permetta di scrivere sulla variabile File file che è solo una variabile che non punta ad alcun file sul disco.
wingman87
05-05-2010, 15:20
Premetto che non conosco C# e la libreria .NET (sto sfogliando MSDN per risponderti), quindi spero di non dire assurdità, nel caso correggetemi.
Credo tu stia usando le classi sbagliate per risolvere il tuo problema. Se non devi scrivere su un File non dovresti usare questa classe. Oltretutto vedo che è una classe statica, quindi non ha molto senso dichiarare una variabile di questo tipo.
Se quello che ti interessa è scrivere l'immagine in memoria primaria come faresti su un file forse la classe giusta da usare è questa:
http://msdn.microsoft.com/en-us/library/9a84386f%28v=VS.100%29.aspx
Mattyfog
05-05-2010, 15:57
Pff sono un defi ho sbagliato tutto, per assegnare un'immagine al tag devo usare per forza un tipo che appartiene alla classe TagLib che sto usando.
Devo solo capire come funziona il tipo TagLib.File.IFileAbstraction
ma sto cercando..
Mattyfog
05-05-2010, 16:20
Dunque ora funziona però sono obbligato a scrivere un file temporaneo sul disco... Si può evitare?
Image webImage = Image.FromStream(responsePic.GetResponseStream());
TagLib.File.IFileAbstraction ifile = new TagLib.File.LocalFileAbstraction("C:\\Users\\Matteo\\prova");
StreamWriter streamwriter = new StreamWriter(ifile.WriteStream);
Stream stream = streamwriter.BaseStream;
webImage.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
streamwriter.Close(); stream.Close();
TagLib.Picture immagine = TagLib.Picture.CreateFromFile(ifile);
tag[a].Pictures = new TagLib.IPicture[] { immagine };
tag[a].Pictures[0].Type = TagLib.PictureType.FrontCover;
wingman87
05-05-2010, 16:25
Dove si può trovare la documentazione di questa libreria?
EDIT: un'altra cosa... ma in pratica cosa vuoi fare? Potrebbe essere inevitabile salvare l'immagine su file
!k-0t1c!
05-05-2010, 20:46
Questo dovrebbe fare al caso tuo
Image webImage = Image.FromStream(responsePic.GetResponseStream());
TagLib.ByteVector imageData;
using(var memoryStream = new MemoryStream())
{
webImage.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
imageData = new TagLib.ByteVector(memoryStream.ToArray());
}
TagLib.Picture immagine = new TagLib.Picture(imageData);
tag[a].Pictures = new TagLib.IPicture[] { immagine };
tag[a].Pictures[0].Type = TagLib.PictureType.FrontCover;
Mattyfog
05-05-2010, 21:52
Si grazie perfetto funziona!
E al contrario? Per ricavare una variabile di tipo image dal tag?
!k-0t1c!
05-05-2010, 22:05
Dato un'oggetto TagLib.Image puoi usare la proprietà Data per avere il ByteVector e la proprietà Data del ByteVector per avere l'array di bytes. Wrappa i dati in un MemoryStream e usa Image.FromStream
Mattyfog
05-05-2010, 22:27
Capito, domani provo, grazie a tutti!
Mattyfog
06-05-2010, 17:16
Ho solo un problema, non so come convertire un System.Drawing.Image in un System.Windows.Controls.Image ...
Come faccio?
!k-0t1c!
06-05-2010, 17:32
Ho solo un problema, non so come convertire un System.Drawing.Image in un System.Windows.Controls.Image ...
Come faccio?
Non lo fai. Usi un PictureBox.
Mattyfog
06-05-2010, 17:34
Non posso perchè sto lavorando in wpf.
Mattyfog
06-05-2010, 18:07
TagLib.ByteVector bv = tag[0].Pictures[0].Data;
System.Drawing.Image immagine;
BitmapImage bitmap = new BitmapImage();
using (var ms = new MemoryStream())
{
ms.Write(bv.ToArray(), 0, bv.Count);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
ms.SetLength(0);
ms.Position = 0;
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);//qui ricevo l'errore
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.EndInit();
}
System.Windows.Media.ImageSource source = bitmap;
System.Drawing.Image image_album.Source = source;
Durante l'esecuzione il programma viene interrotto per un errore generico GDI+ .
Tra l'altro è giusto scrivere ms.SetLength(0); ms.Position = 0; per svuotare e riutilizzare il memorystream o bisogna usare sm.Flush()?
!k-0t1c!
07-05-2010, 11:57
TagLib.ByteVector bv = tag[0].Pictures[0].Data;
System.Drawing.Image immagine;
BitmapImage bitmap = new BitmapImage();
using (var ms = new MemoryStream())
{
ms.Write(bv.ToArray(), 0, bv.Count);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
ms.SetLength(0);
ms.Position = 0;
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);//qui ricevo l'errore
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.EndInit();
}
System.Windows.Media.ImageSource source = bitmap;
System.Drawing.Image image_album.Source = source;
Durante l'esecuzione il programma viene interrotto per un errore generico GDI+ .
Tra l'altro è giusto scrivere ms.SetLength(0); ms.Position = 0; per svuotare e riutilizzare il memorystream o bisogna usare sm.Flush()?
Il memorystream non lo devi svuotare. E' sbagliata l'idea prima del codice. Ma soprattutto nel momento in cui provi a fare il save di un memorystream di lunghezza 0 naturalmente GDI+ non sa come creare l'immagine (a partire da 0 bytes).
Il codice corretto sarebbe:
TagLib.ByteVector bv = tag[0].Pictures[0].Data;
System.Drawing.Image immagine;
BitmapImage bitmap = new BitmapImage();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
using (var ms = new MemoryStream())
{
ms.Write(bv.Data, 0, bv.Count);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.EndInit();
}
System.Windows.Media.ImageSource source = bitmap;
System.Drawing.Image image_album.Source = source;
Gli errori:
bv.ToArray() causa la creazione di un nuovo array tramite l'uso dell'interfaccia IEnumerable (molto lento, contando che bv.Data è già un array a cui puoi accedere)
settare la lunghezza dello stream a 0 o la posizione dello stream
pensare che lo stream sia riutilizzabile: appunto perché è in un blocco using dovresti sapere che alla fine del blocco using o se si verificano eccezioni durante l'esecuzione del blocco using verrà chiamato il metodo Dispose sullo stream e quindi sarà inutilizzabile
Mattyfog
07-05-2010, 13:19
Durante l'esecuzione ottengo l'errore:
Impossibile trovare un componente di imaging adatto per il completamento dell'operazione.
alla comando bitmap.EndInit();
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.