Loading Album art with TagLib sharp and then saving it to same/different file in C# causes memory error

走远了吗. 提交于 2019-12-04 12:28:36

问题


My application lists all MP3's in a directory and when the user selects a file it loads the tag info, including album art. The art is loaded into a variable to be used when the user saves the data. The art is also loaded into a picture frame for the user to see.

// Global to all methods
System.Drawing.Image currentImage = null;

// In method onclick of the listbox showing all mp3's
TagLib.File f = new TagLib.Mpeg.AudioFile(file);
if (f.Tag.Pictures.Length > 0)
{
      TagLib.IPicture pic = f.Tag.Pictures[0];
      MemoryStream ms = new MemoryStream(pic.Data.Data);
      if (ms != null && ms.Length > 4096)
      {
           currentImage = System.Drawing.Image.FromStream(ms);
           // Load thumbnail into PictureBox
           AlbumArt.Image = currentImage.GetThumbnailImage(100,100, null, System.IntPtr.Zero);
      }
      ms.Close();
}

// Method to save album art
TagLib.Picture pic = new TagLib.Picture();
pic.Type = TagLib.PictureType.FrontCover;
pic.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
pic.Description = "Cover";
MemoryStream ms = new MemoryStream();
currentImage.Save(ms, ImageFormat.Jpeg); // <-- Error occurs on this line
ms.Position = 0;
pic.Data = TagLib.ByteVector.FromStream(ms);
f.Tag.Pictures = new TagLib.IPicture[1] { pic };
f.save();
ms.Close();

If I load the image and try to save it right away I get this "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." If I try to save currentImage as a ImageFormat.Bmp I get this "A generic error occurred in GDI+."

My save method works correctly if I load an image from a url like this:

WebRequest req = WebRequest.Create(urlToImg);
WebResponse response = req.GetResponse();
Stream stream = response.GetResponseStream();
currentImage = Image.FromStream(stream);
stream.Close();

So I'm guessing there is an issue with the way that I am loading the image into currentImage when the user selects an MP3 from the listbox.

I have found a lot of examples of loading and saving images to mp3's but no one seems to be having this issue when they try to save the are immediately after loading it.


回答1:


Thanks for the help Jim but I couldn't really get it working using the 'using' blocks so I'm guessing the stream was still closing somewhere. I found another way to do what I was looking for by storing/saving a byte[] instead of an Image. And then just saving it using:

using (MemoryStream ms = new MemoryStream(currentImageBytes))
{
    pic.Data = TagLib.ByteVector.FromStream(ms);
    f.Tag.Pictures = new TagLib.IPicture[1] { pic };
    if (save)
        f.Save();
}



回答2:


Your stream stuff should be in using blocks, which will dispose of your goods automagically and close them too. Not terribly important, but easier to manage.

Your generic GDI+ error is likely because you are trying to perform an operation or call a method on a file for which the stream is already closed.

Check it out...




回答3:


your method isn't really false, only a few things had to be changed:

// Method to save album art
TagLib.Picture pic = new TagLib.Picture();
pic.Type = TagLib.PictureType.FrontCover;
pic.MimeType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
pic.Description = "Cover";
MemoryStream ms = new MemoryStream();
currentImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); // <-- Error doesn't occur anymore
ms.Position = 0;
pic.Data = TagLib.ByteVector.FromStream(ms);
f.Tag.Pictures = new TagLib.IPicture[1] { pic };
f.save();
ms.Close();


来源:https://stackoverflow.com/questions/13404957/loading-album-art-with-taglib-sharp-and-then-saving-it-to-same-different-file-in

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!