一直以来存在这么一个问题,就是当用户上传的Flash文件时都需要附带输入Flash的宽和高,否则显示的时候由于不知道这些数值而导致Flash比例不正常。
近日我做网站也涉及到了这方面的问题,于是打算解决一下。
首先在Google上搜索,可以找到获取Flash宽和高的java script,但是是在Flash载入后而不是之前,而且也没法动态更改object标记的宽和高,最重要的是有Flash Player的安全警告信息,所以放弃了在客户端读取,转而考虑服务器端。
在VS内导入flash.ocx控件,试图获取Flash文件信息,结果在调用TGetProperty()方法是总是以返回E_FAIL错误而失败,如果哪位高手知道如何在.NET下使用,欢迎指明。
想来想去,只剩下一个办法,也是最可行的办法,就是直接读取Flash文件并分析格式。
在Google上搜到 Macromedia Flash (SWF) File Format Specification Version 7 (http://www.xiaowowo.com/gt_book/new/flashfileformat.rar)
经过反复阅读和尝试,最终写出了 FlashInfo 类,调用方法如下:
FlashInfo flashInfo = new FlashInfo(@"c:\test.swf"); // 构造函数,参数是Flash文件地址
Console.WriteLine(string.Format("Version: {0}", flashInfo.Version)); // Flash版本
Console.WriteLine(string.Format("Compressed: {0}", flashInfo.IsCompressed)); //是否被压缩
Console.WriteLine(string.Format("Width: {0}", flashInfo.Width)); // Flash的宽度
Console.WriteLine(string.Format("Height: {0}", flashInfo.Height)); // Flash的高度
Console.WriteLine(string.Format("FrameRate: {0}", flashInfo.FrameRate)); // 帧速率
Console.WriteLine(string.Format("FrameCount: {0}", flashInfo.FrameCount)); // 总帧数
Console.WriteLine(string.Format("FileLength: {0}", flashInfo.FileLength)); // 未压缩时的文件大小
自从Flash格式版本6以后,增加了可压缩选项,用的是ZLib压缩,为了支持压缩格式,只好又在Google上找了一个ZLib .NET Wrapper (http://zlibnetwrapper.sourceforge.net/)
FlashInfo 类的源代码和编译好的库文件提供给有同样需求的朋友下载:http://files.cnblogs.com/gmm/FlashInfo.zip
ASP.NET技术网站:http://www.singletowm.com/
在一篇帖子中有人询问如何能将用户照片放入Excel。
先录制了一个宏,得到的结果是:
ActiveSheet.Pictures.Insert("D:\tt.bmp").Select
然而,在C#中,WorkSheet类似乎并不直接支持Pictures.Insert这样的方法。而在MSDN
网站上,几篇Office开发文档介绍的也只是常见的Application、WorkBook、Sheet这些对
象如何读写。最后,还是看了VBA的帮助,才找到了解决的办法,也仍然非常简单:
|
Excel.Worksheet xSheet=( Excel.Worksheet)xBook.Sheets[1];
xSheet.Shapes.AddPicture("D:\\tt.bmp", MsoTriState.msoFalse ,
MsoTriState.msoTrue,10,10,150,150); |
就可以了。其中,第二、三个参数分别表示是否链接到文件、是否在文档中保存图片
信息(还是只保存链接信息)。
ASP.NET技术网站:http://www.singletowm.com
当我们用winamp软件听音乐时,播放清单就自动将这些信息读出来。大部分人都喜欢从网上下载音乐,但下载下来的MP3文件名都是文件上传系统自动取名的
下面以C#为工具,把开发过程写出来。
一首MP3的额外信息存放在文件的最后面,共占128个字节,其中包括以下的内容(我们定义一个结构说明):
public struct Mp3Info
{
public string identify;//TAG,三个字节
public string Title;//歌曲名,30个字节
public string Artist;//歌手名,30个字节
public string Album;//所属唱片,30个字节
public string Year;//年,4个字符
public string Comment;//注释,28个字节
public char reserved1;//保留位,一个字节
public char reserved2;//保留位,一个字节
public char reserved3;//保留位,一个字节
}
所以,我们只要把MP3文件的最后128个字节分段读出来并保存到该结构里就可以了。函数定义如下:
///
/// 获取MP3文件最后128个字节
///
///
///
返回字节数组
private byte[] getLast128(string FileName)
{
FileStream fs = new FileStream(FileName,FileMode.Open,FileAccess.Read);
Stream stream = fs;
stream.Seek(-128,SeekOrigin.End);
const int seekPos = 128;
int rl = 0;
byte[] Info = new byte[seekPos];
rl = stream.Read(Info,0,seekPos);
fs.Close();
stream.Close();
return Info;
} 再对上面返回的字节数组分段取出,并保存到Mp3Info结构中返回。
///
/// 获取MP3歌曲的相关信息
///
///
///
返回一个Mp3Info结构
private Mp3Info getMp3Info(byte[] Info)
{
Mp3Info mp3Info = new Mp3Info();
string str = null;
int i;
int position = 0;//循环的起始值
int currentIndex = 0;//Info的当前索引值
//获取TAG标识
for(i = currentIndex;i
{
str = str+(char)Info[i];
position++;
}
currentIndex = position;
mp3Info.identify = str;
//获取歌名
str = null;
byte[] bytTitle = new byte[30];//将歌名部分读到一个单独的数组中
int j = 0;
for(i = currentIndex;i
{
bytTitle[j] = Info[i];
position++;
j++;
}
currentIndex = position;
mp3Info.Title = this.byteToString(bytTitle);
//获取歌手名
str = null;
j = 0;
byte[] bytArtist = new byte[30];//将歌手名部分读到一个单独的数组中
for(i = currentIndex;i
{
bytArtist[j] = Info[i];
position++;
j++;
}
currentIndex = position;
mp3Info.Artist = this.byteToString(bytArtist);
//获取唱片名
str = null;
j = 0;
byte[] bytAlbum = new byte[30];//将唱片名部分读到一个单独的数组中
for(i = currentIndex;i
{
bytAlbum[j] = Info[i];
position++;
j++;
}
currentIndex = position;
mp3Info.Album = this.byteToString(bytAlbum);
//获取年
str = null;
j = 0;
byte[] bytYear = new byte[4];//将年部分读到一个单独的数组中
for(i = currentIndex;i
{
bytYear[j] = Info[i];
position++;
j++;
}
currentIndex = position;
mp3Info.Year = this.byteToString(bytYear);
//获取注释
str = null;
j = 0;
byte[] bytComment = new byte[28];//将注释部分读到一个单独的数组中
for(i = currentIndex;i
{
bytComment[j] = Info[i];
position++;
j++;
}
currentIndex = position;
mp3Info.Comment = this.byteToString(bytComment);
//以下获取保留位
mp3Info.reserved1 = (char)Info[++position];
mp3Info.reserved2 = (char)Info[++position];
mp3Info.reserved3 = (char)Info[++position];
return mp3Info;
}
上面程序用到下面的方法:
///
/// 将字节数组转换成字符串
///
///
/// 返回转换后的字符串
private string byteToString(byte[] b)
{
Encoding enc = Encoding.GetEncoding("GB2312");
string str = enc.GetString(b);
str = str.Substring(0,str.IndexOf('\0') >= 0 ? str.IndexOf('\0') : str.Length);//去掉无用字符
return str;
} 改名怎么办呢?我们按(演唱者)歌名 的格式对歌曲进行改名,程序如下:
///
/// 更改文件名
///
///
///
private bool ReName(string filePath)
{
if(File.Exists(filePath))
{
Mp3Info mp3Info = new Mp3Info();
mp3Info = this.getMp3Info(this.getLast128(filePath));//读出文件信息
mp3Info.Artist = this.DeleteNotValue(mp3Info.Artist);
mp3Info.Title = this.DeleteNotValue(mp3Info.Title);
if(mp3Info.Artist.Trim().Length==0)
{
mp3Info.Artist="未命名";
}
if(mp3Info.Title.Trim().Length==0)
{
mp3Info.Title="未知名歌曲";
}
try
{
//更名
File.Move(filePath,filePath.Substring(0,filePath.ToLower().LastIndexOf("\\")).Trim() + "\\" + "(" + mp3Info.Artist.Trim() + ")" +mp3Info.Title.Trim() + ".mp3");
return true;
}
catch(Exception)
{
return false;
}
}
else
{
return false;
}
}
ASP.NET技术网站:http://www.singletowm.com/