This class requires ICSharpCode.SharpZipLib.dll. You can download it from here or ICSharpCode.
- Use GetDimensions(String filePath) method whenever you want the dimensions of the swf file that resides on your server. Give the complete file path as a parameter.
- Use GetDimensions(Stream stream) method whenever you want to find the swf file dimensions from the input stream (Ex: Asp.net file upload control's PostedFile.InputStream object.), it can be of any inputStream. Here you no need to save the file on to the server.
Usage:
//Use when the file resides on your server. try { SwfParser swfParser = new SwfParser(); Rectangle rectangle = swfParser.GetDimensions(filePath); int width=rectangle.Width; int height=rectangle.Height; } catch (Exception ex) { return "There is a problem with the swf file."; } //Use when you want to use file upload control's input stream.(it may be any input stream) try { SwfParser swfParser = new SwfParser(); Rectangle rectangle = swfParser.GetDimensions(uploadedfile.PostedFile.InputStream); int width=rectangle.Width; int height=rectangle.Height; } catch (Exception ex) { return "There is a problem with the swf file."; }
Here is the SwfParser class:
using System; using System.Text; using System.IO; using System.Drawing; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; public class SwfParser { public Rectangle GetDimensions(String filePath) { using (FileStream stream = File.OpenRead(filePath)) { return GetDimensions(stream); } } public Rectangle GetDimensions(Stream stream) { Stream inputStream = null; byte[] signature = new byte[8]; byte[] rect = new byte[8]; stream.Read(signature, 0, 8); if ("CWS" == System.Text.Encoding.ASCII.GetString(signature, 0, 3)) { inputStream = new InflaterInputStream(stream); } else { inputStream = stream; } inputStream.Read(rect, 0, 8); int nbits = rect[0] >> 3; rect[0] = (byte)(rect[0] & 0x07); String bits = ByteArrayToBitString(rect); bits = bits.Remove(0, 5); int[] dims = new int[4]; for (int i = 0; i < 4; i++) { char[] dest = new char[nbits]; bits.CopyTo(0, dest, 0, bits.Length>nbits ? nbits : bits.Length); bits = bits.Remove(0, bits.Length > nbits ? nbits : bits.Length); dims[i] = BitStringToInteger(new String(dest)) / 20; } return new Rectangle(0, 0, dims[1] - dims[0], dims[3] - dims[2]); } private int BitStringToInteger(String bits) { int converted = 0; for (int i = 0; i < bits.Length; i++) { converted = (converted << 1) + (bits[i] == '1' ? 1 : 0); } return converted; } private String ByteArrayToBitString(byte[] byteArray) { byte[] newByteArray = new byte[byteArray.Length]; Array.Copy(byteArray, newByteArray, byteArray.Length); String converted = ""; for (int i = 0; i < newByteArray.Length; i++) { for (int j = 0; j < 8; j++) { converted += (newByteArray[i] & 0x80) > 0 ? "1" : "0"; newByteArray[i] <<= 1; } } return converted; } }
10 comments:
It works! Thanks
Very Nice!!! =)
Great post. However, I'm getting the height off by 2px for some swf files. Changing the line:
BitStringToInteger(new String(dest)) / 20
To:
Math.Round(BitStringToInteger(new String(dest)) / 20.0)
made it off by 1px, yet I need it to be exact. Any ideas?
cut/paste and working, thanks!
Epic, and it works with flash player 10. Thanks!
Great gimmick, thank you!
But a tiny remark i have. When using the GetDimensions(Stream stream)-method twice with the same stream-instance, it won't work because the actual stream position has changed and the signature is incorrect (not "CWS"). Therefore the stream's position should reset to 0 after line 21:
byte[] rect = new byte[8];
stream.Position = 0;
stream.Read(signature, 0, 8);
:)
That is great
nice article Thanks.....................
Thanks, it works fine for me!!!!!
Nice, simple and clear article with all files that I was looking for.
Thanks a lot for your solution and big thanks to icsharpcode.net of course.
Great job
Post a Comment