private static void AddEmbeddedPictureToResults(AlbumArtDownloader.Scripts.IScriptResults results, TagLib.IPicture[] embeddedPictures, int embeddedIndex, string filename) { //Create an in-memory copy so that the bitmap file isn't in use, and can be replaced Bitmap bitmap = new Bitmap(new MemoryStream(embeddedPictures[embeddedIndex].Data.Data)); //NOTE: Do not dispose of MemoryStream, or it will cause later saving of the bitmap to throw a generic GDI+ error (annoyingly) results.Add(bitmap, EmbeddedArtHelpers.GetEmbeddedFilePath(Path.GetFileName(filename), embeddedIndex), filename, bitmap.Width, bitmap.Height, null); }
protected override void SearchInternal(string artist, string album, AlbumArtDownloader.Scripts.IScriptResults results) { //Add the pattern used to the history list. CustomSettingsUI.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.DataBind, new System.Threading.ThreadStart(delegate { ((LocalFilesSourceSettings)CustomSettingsUI).mSearchPathPatternBox.AddPatternToHistory(); })); int lastMinImageSizeSet = 0; //Avoid duplicates StringDictionary addedFiles = new StringDictionary(); string pathPattern = GetSearchPath(artist, album); foreach (string alternate in pathPattern.Split('|')) { int? embeddedIndex = null; string unembeddedPathPattern = alternate; if (EmbeddedArtHelpers.IsEmbeddedArtPath(alternate)) { //TODO: Allow a pattern to specify multiple embedded images as "<?>" or similar. int i; EmbeddedArtHelpers.SplitToFilenameAndIndex(alternate, out unembeddedPathPattern, out i); embeddedIndex = i; } //Match path with wildcards foreach (string filename in Common.ResolvePathPattern(unembeddedPathPattern)) { if (!addedFiles.ContainsKey(filename)) //Don't re-add a file that's already been added { addedFiles.Add(filename, null); if (embeddedIndex.HasValue) { //Read embedded image from file, rather than the file itself as an image TagLib.File fileTags = null; try { fileTags = TagLib.File.Create(filename, TagLib.ReadStyle.None); var embeddedPictures = fileTags.Tag.Pictures; if (embeddedIndex.Value == -1) //Special value indicating "all embedded images" { for (int i = 0; i < embeddedPictures.Length; i++) { AddEmbeddedPictureToResults(results, embeddedPictures, i, filename); } } else if (embeddedPictures.Length > embeddedIndex.Value) { //Found the embedded image AddEmbeddedPictureToResults(results, embeddedPictures, embeddedIndex.Value, filename); } else { System.Diagnostics.Trace.WriteLine("Skipping file missing specified embedded image in local file search: " + EmbeddedArtHelpers.GetEmbeddedFilePath(filename, embeddedIndex.Value)); } } catch (Exception e) { System.Diagnostics.Trace.WriteLine("Skipping unreadable embedded image from file in local file search: " + EmbeddedArtHelpers.GetEmbeddedFilePath(filename, embeddedIndex.Value)); System.Diagnostics.Trace.Indent(); System.Diagnostics.Trace.WriteLine(e.Message); System.Diagnostics.Trace.Unindent(); } finally { if (fileTags != null) { fileTags.Mode = TagLib.File.AccessMode.Closed; } } } else { //Each filename is potentially an image, so try to load it try { using (var filestream = File.OpenRead(filename)) { var decoder = BitmapDecoder.Create(filestream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None); //Don't cache, only want the width and height, and delay creation as no need to actually read the data. var frame = decoder.Frames[0]; int width = frame.PixelWidth; int height = frame.PixelHeight; results.Add(File.OpenRead(filename), Path.GetFileName(filename), filename, width, height, null); if (SetMinimumSizeFilter) { var minImageSize = Math.Min(width, height); if (lastMinImageSizeSet == 0) { Properties.Settings.Default.UseMinimumImageSize = true; Properties.Settings.Default.MinimumImageSize = lastMinImageSizeSet = minImageSize; } else if (Properties.Settings.Default.UseMinimumImageSize && Properties.Settings.Default.MinimumImageSize == lastMinImageSizeSet) // Don't override during a search if the user has made manual changes { Properties.Settings.Default.MinimumImageSize = Math.Max(lastMinImageSizeSet, minImageSize); // If this image is bigger, use it as the minimum size } } } } catch (Exception e) { System.Diagnostics.Trace.WriteLine("Skipping unreadable file in local file search: " + filename); System.Diagnostics.Trace.Indent(); System.Diagnostics.Trace.WriteLine(e.Message); System.Diagnostics.Trace.Unindent(); } } } } } }
private static void AddEmbeddedPictureToResults(AlbumArtDownloader.Scripts.IScriptResults results, TagLib.IPicture[] embeddedPictures, int embeddedIndex, string filename) { results.Add(new MemoryStream(embeddedPictures[embeddedIndex].Data.Data), EmbeddedArtHelpers.GetEmbeddedFilePath(Path.GetFileName(filename), embeddedIndex), filename, -1, -1, null); }
protected override void SearchInternal(string artist, string album, AlbumArtDownloader.Scripts.IScriptResults results) { //Add the pattern used to the history list. CustomSettingsUI.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.DataBind, new System.Threading.ThreadStart(delegate { ((LocalFilesSourceSettings)CustomSettingsUI).mSearchPathPatternBox.AddPatternToHistory(); })); //Avoid duplicates StringDictionary addedFiles = new StringDictionary(); string pathPattern = GetSearchPath(artist, album); foreach (string alternate in pathPattern.Split('|')) { int? embeddedIndex = null; string unembeddedPathPattern = alternate; if (EmbeddedArtHelpers.IsEmbeddedArtPath(alternate)) { //TODO: Allow a pattern to specify multiple embedded images as "<?>" or similar. int i; EmbeddedArtHelpers.SplitToFilenameAndIndex(alternate, out unembeddedPathPattern, out i); embeddedIndex = i; } //Match path with wildcards foreach (string filename in Common.ResolvePathPattern(unembeddedPathPattern)) { if (!addedFiles.ContainsKey(filename)) //Don't re-add a file that's already been added { addedFiles.Add(filename, null); if (embeddedIndex.HasValue) { //Read embedded image from file, rather than the file itself as an image TagLib.File fileTags = null; try { fileTags = TagLib.File.Create(filename, TagLib.ReadStyle.None); var embeddedPictures = fileTags.Tag.Pictures; if (embeddedIndex.Value == -1) //Special value indicating "all embedded images" { for (int i = 0; i < embeddedPictures.Length; i++) { AddEmbeddedPictureToResults(results, embeddedPictures, i, filename); } } else if (embeddedPictures.Length > embeddedIndex.Value) { //Found the embedded image AddEmbeddedPictureToResults(results, embeddedPictures, embeddedIndex.Value, filename); } else { System.Diagnostics.Trace.WriteLine("Skipping file missing specified embedded image in local file search: " + EmbeddedArtHelpers.GetEmbeddedFilePath(filename, embeddedIndex.Value)); } } catch (Exception e) { System.Diagnostics.Trace.WriteLine("Skipping unreadable embedded image from file in local file search: " + EmbeddedArtHelpers.GetEmbeddedFilePath(filename, embeddedIndex.Value)); System.Diagnostics.Trace.Indent(); System.Diagnostics.Trace.WriteLine(e.Message); System.Diagnostics.Trace.Unindent(); } finally { if (fileTags != null) { fileTags.Mode = TagLib.File.AccessMode.Closed; } } } else { //Each filename is potentially an image, so try to load it try { IntPtr hBitmap; int status = GdipCreateBitmapFromFile(filename, out hBitmap); GdipDisposeImage(new HandleRef(this, hBitmap)); if (status == 0) { //Successfully opened as image //Create an in-memory copy so that the bitmap file isn't in use, and can be replaced byte[] fileBytes = File.ReadAllBytes(filename); //Read the file, closing it after use Bitmap bitmap = new Bitmap(new MemoryStream(fileBytes)); //NOTE: Do not dispose of MemoryStream, or it will cause later saving of the bitmap to throw a generic GDI+ error (annoyingly) results.Add(bitmap, Path.GetFileName(filename), filename, bitmap.Width, bitmap.Height, null); } else { System.Diagnostics.Trace.WriteLine("Skipping non-bitmap file in local file search: " + filename); } } catch (Exception e) { System.Diagnostics.Trace.WriteLine("Skipping unreadable file in local file search: " + filename); System.Diagnostics.Trace.Indent(); System.Diagnostics.Trace.WriteLine(e.Message); System.Diagnostics.Trace.Unindent(); } } } } } }