From a19d53b5a8bac1ccb5fcd20e4298c2714d2bc280 Mon Sep 17 00:00:00 2001 From: Sahand Date: Tue, 25 Feb 2014 23:11:10 -0800 Subject: [PATCH] Improved handling of picture frames. Passes all tests now. --- ID3/ID3.csproj | 4 ++ .../Writers/PictureFrameWriter.cs | 20 +++--- ID3/Source/Frames/Other/PictureFrame.cs | 30 +++++--- ID3/Source/Utils/ImagingHelpers.cs | 68 +++++++++++++++++++ 4 files changed, 101 insertions(+), 21 deletions(-) create mode 100644 ID3/Source/Utils/ImagingHelpers.cs diff --git a/ID3/ID3.csproj b/ID3/ID3.csproj index 3eb1e31..5d51821 100644 --- a/ID3/ID3.csproj +++ b/ID3/ID3.csproj @@ -186,6 +186,7 @@ + @@ -203,4 +204,7 @@ --> + + + \ No newline at end of file diff --git a/ID3/Source/Frame Implementations/Writers/PictureFrameWriter.cs b/ID3/Source/Frame Implementations/Writers/PictureFrameWriter.cs index ea5cfd3..c2e77fc 100644 --- a/ID3/Source/Frame Implementations/Writers/PictureFrameWriter.cs +++ b/ID3/Source/Frame Implementations/Writers/PictureFrameWriter.cs @@ -17,16 +17,14 @@ public override void WriteToStream(System.IO.Stream stream) PictureFrame frame=(PictureFrame)this.FrameToWrite; List fields=new List(); + String imageFormat = Utils.ImagingHelpers.ImageFormatToExtension(frame.Picture.RawFormat); + // Declare the fields to write. fields.Add(new SingleByteField((byte)this.Encoding)); - fields.Add(new FixedLengthAsciiTextField("JPG")); + fields.Add(new FixedLengthAsciiTextField(imageFormat)); fields.Add(new SingleByteField((byte)frame.PictureType)); fields.Add(TextField.CreateTextField(frame.Description, this.Encoding)); - - System.IO.MemoryStream memoryBuffer=new System.IO.MemoryStream(); - frame.Picture.Save(memoryBuffer, System.Drawing.Imaging.ImageFormat.Jpeg); - fields.Add(new BinaryField(memoryBuffer.GetBuffer(), 0, (int)memoryBuffer.Length)); - memoryBuffer.Close(); + fields.Add(new BinaryField(frame.RawData, 0, (int)frame.RawData.Length)); // Write the header int length=0; @@ -56,16 +54,14 @@ public override void WriteToStream(System.IO.Stream stream) PictureFrame frame=(PictureFrame)this.FrameToWrite; List fields=new List(); + string imageMimeType = Utils.ImagingHelpers.ImageFormatToMimeType (frame.Picture.RawFormat); + // Declare the fields to write. fields.Add(new SingleByteField((byte)this.Encoding)); - fields.Add(TextField.CreateTextField("image/jpeg", EncodingScheme.Ascii)); + fields.Add(TextField.CreateTextField(imageMimeType, EncodingScheme.Ascii)); fields.Add(new SingleByteField((byte)frame.PictureType)); fields.Add(TextField.CreateTextField(frame.Description, this.Encoding)); - - System.IO.MemoryStream memoryBuffer=new System.IO.MemoryStream(); - frame.Picture.Save(memoryBuffer, System.Drawing.Imaging.ImageFormat.Jpeg); - fields.Add(new BinaryField(memoryBuffer.GetBuffer(), 0, (int)memoryBuffer.Length)); - memoryBuffer.Close(); + fields.Add(new BinaryField(frame.RawData, 0, (int)frame.RawData.Length)); // Write the header int length=0; diff --git a/ID3/Source/Frames/Other/PictureFrame.cs b/ID3/Source/Frames/Other/PictureFrame.cs index 27da1e6..065428a 100644 --- a/ID3/Source/Frames/Other/PictureFrame.cs +++ b/ID3/Source/Frames/Other/PictureFrame.cs @@ -20,21 +20,25 @@ public string Description } } - private byte[] _raw_data = null; - private System.Drawing.Image _image; - public System.Drawing.Image Picture + private byte[] _rawData = null; + public byte[] RawData { - get + get { - return _image; + if (this._rawData == null) + { + this.LoadRawDataFromImage(); + } + return this._rawData; } } - public byte[] RawData + private System.Drawing.Image _image; + public System.Drawing.Image Picture { - get + get { - return this._raw_data; + return _image; } } @@ -51,6 +55,14 @@ public PictureType PictureType } } + protected void LoadRawDataFromImage() + { + System.IO.MemoryStream memoryBuffer=new System.IO.MemoryStream(); + this._image.Save(memoryBuffer, this._image.RawFormat); + this._rawData = memoryBuffer.GetBuffer(); + memoryBuffer.Close(); + } + protected PictureFrame(string description, PictureType pictureType) : base() { @@ -81,7 +93,7 @@ public PictureFrame(byte[] raw_data, System.Drawing.Image image, string descript { throw new ArgumentNullException("The passed image raw data can not be null."); } - this._raw_data = raw_data; + this._rawData = raw_data; } diff --git a/ID3/Source/Utils/ImagingHelpers.cs b/ID3/Source/Utils/ImagingHelpers.cs new file mode 100644 index 0000000..1a7d58a --- /dev/null +++ b/ID3/Source/Utils/ImagingHelpers.cs @@ -0,0 +1,68 @@ +using System; +using System.Drawing.Imaging; + +namespace Achamenes.ID3.Utils +{ + public class ImagingHelpers + { + public static string ImageFormatToMimeType(ImageFormat imageFormat) + { + foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageDecoders()) + { + if (codec.FormatID == imageFormat.Guid) + { + return codec.MimeType; + } + } + return "application/octet-stream"; + } + + // Taken from http://www.java2s.com/Code/CSharp/File-Stream/ImageFormattoExtension.htm + // And modified. + public static string ImageFormatToExtension(ImageFormat imageFormat) + { + if (imageFormat.Equals(ImageFormat.Bmp)) + { + return "BMP"; + } + else if (imageFormat.Equals(ImageFormat.MemoryBmp)) + { + return "BMP"; + } + else if (imageFormat.Equals(ImageFormat.Wmf)) + { + return "EMF"; + } + else if (imageFormat.Equals(ImageFormat.Wmf)) + { + return "WMF"; + } + else if (imageFormat.Equals(ImageFormat.Gif)) + { + return "GIF"; + } + else if (imageFormat.Equals(ImageFormat.Jpeg)) + { + return "JPG"; + } + else if (imageFormat.Equals(ImageFormat.Png)) + { + return "PNG"; + } + else if (imageFormat.Equals(ImageFormat.Tiff)) + { + return "TIF"; + } + else if (imageFormat.Equals(ImageFormat.Exif)) + { + return "EXF"; + } + else if (imageFormat.Equals(ImageFormat.Icon)) + { + return "ICO"; + } + return ""; + } + } +} +