废话不多说直接上精华。
下面是图片操作的一些关键代码:
图片操作类
需求是得到一些图片的信息存入数据库,其中图片的宽高可通过system.Drawing.Image查看。
一切从FileInfo开始
- OpenFileDialog open = new OpenFileDialog();
- if ((bool)open.ShowDialog())
- {
- //图片文件
- FileInfo file = new FileInfo(open.FileName);}
得到图片(Image):
#region 静态方法
/// <summary>
/// 从图片文件(FileInfo)读取流并生成System.Drawing.Image
/// </summary>
/// <param name="file">图片文件(FileInfo)</param>
/// <returns>Image图片</returns>
public static Image GetImageFromFileInfo(FileInfo file)
{
return Image.FromStream(file.OpenRead());
}
注意:WPF里面有个Window.Controls.Image,即控件Image和Window.Drawing.Image,注意区分。
得到图片缩略图
- /// <summary>
- /// 得到图片固定大小的缩略图(调用Image.GetThumbnailImage静态方法)
- /// </summary>
- /// <param name="image">原图</param>
- /// <param name="size">缩略图尺寸</param>
- /// <returns>固定大小的缩略图</returns>
- public static Image getThumbnailImage(Point size,Image image)
- {
- Bitmap bitmap = new Bitmap(image);
- return bitmap.GetThumbnailImage(size.X, size.Y, null, IntPtr.Zero);
- }
- /// <summary>
- /// 得到图片固定大小的缩略图的二进制数据
- /// </summary>
- /// <param name="size">原图</param>
- /// <param name="size">缩略图尺寸</param>
- /// <returns>固定大小的缩略图的二进制</returns>
- public static byte[] getByteThumbnailImage(Point size, Image image)
- {
- Image myImage=getThumbnailImage(size, image);
- MemoryStream stream = new MemoryStream();
- myImage.Save(stream, myImage.RawFormat);
- return stream.ToArray();
- }
注意:得到Byte[]即二进制数据可存入数据库里面去对应的类型是Image(Binary)
界面上显示
上面说到过,此时的显示就需要Image控件了,将System.Drawing.Image作为Image控件的图片源
/// <summary>
/// 从System.Drawing.Image转换成GDI位图
/// 调用System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap
/// 得到System.Windows.Media.ImageSource
/// </summary>
/// <param name="image">System.Drawing.Image</param>
/// <returns>System.Windows.Media.ImageSource</returns>
public static ImageSource GetImageSourceFromImage(Image image)
{
Bitmap bitmap = new Bitmap(image);
IntPtr hBitmap = bitmap.GetHbitmap();
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
视频处理
需求:得到视频一些信息存入数据库,有点难度是视频特有属性(FileInfo得不到的),比如视频宽高,视频时长。这里我们借助ffmpeg这个开源免费跨平台的视频和音频流方案。
这是个很强大的东东啊,不信,你百度看看。下面是我研究了一天得到的,借助这强大的东东完成我想得到的效果,我封装了个类,直接看把。
#region 字段
/// <summary>
/// 视频转换工具的路径
/// </summary>
string ffmpeg = AppDomain.CurrentDomain.BaseDirectory + "Resource/Tools/ffmpeg.exe";
/// <summary>
/// 提过本地进程访问
/// </summary>
Process process;
#endregion
#region 属性
/// <summary>
/// 是否初始化成功
/// </summary>
public bool IsFinishInitial { get; set; }
/// <summary>
/// During时长(D)、Width视频宽(W)、视频高(H)的联合字符串
/// 例子:00:04:32.46x800x600
/// </summary>
public string StrDWH { get; set; }
#endregion
#region 构造
public VideoOperation()
{
if (!System.IO.File.Exists(ffmpeg))
{
//若不存在
IsFinishInitial = false;
return;
}
//初始化ffmpeg进程
process = new Process();
//不启动新窗口
process.StartInfo.CreateNoWindow = true;
//不用操作系统shell
process.StartInfo.UseShellExecute = false;
//设置启动程序路径
process.StartInfo.FileName = ffmpeg;
//初始化成功
IsFinishInitial = true;
}
#endregion
#region 方法
/// <summary>
/// 截取视频截图
/// 同时异步从视频读取信息During时长(D)、Width视频宽(W)、视频高(H)
/// 存在字符串StrDWH
/// </summary>
/// <param name="fileName">需要截取图片的视频路径</param>
/// <param name="imgFile">截取图片后保存的图片路径</param>
/// <param name="imgSize">获取截取图片的大小,默认"100x100"</param>
public void GetDWHFromVideo(string fileName, string imgFile ,string imgSize="100x100")
{
//就看视频
//获取截图后保存的路径
string flv_img = imgFile;
// pss = new Process();
//设置启动程序的路径
process.StartInfo.Arguments = " -i \"" + fileName + "\" -y -f image2 -ss 2 -vframes 1 -s " + imgSize + " " + flv_img;
process.StartInfo.RedirectStandardError = true;//输出信息第一步,基础输出重定向
DataReceivedEventHandler handler=null;
process.ErrorDataReceived +=handler= (s, e) =>//输出信息第二步,调用接收到信息时执行的函数
{
if (String.IsNullOrEmpty(e.Data)) return;
string dataReceived = e.Data.Trim();
if (dataReceived.StartsWith("Duration:"))
{
//例子: Duration: 01:56:28.47, start: 0.000000, bitrate: 291 kb/s
StrDWH = dataReceived.Split(',')[0].Substring(9);
}
if (dataReceived.Contains("Video:"))
{
//StrDWH += "x"+dataReceived.Split(',')[2].Split('[')[0];
StrDWH += "x" + dataReceived.Split(',')[2].Trim().Split('[')[0];
//不在监听数据接收
process.ErrorDataReceived -= handler;
}
};
//启动
process.Start();
process.BeginErrorReadLine();//输出信息第三步,开始执行
process.WaitForExit();
}
#endregion
顺便写个视频转换方法也贴上好了,
/// <summary>
/// 视频格式转换,转换成指定像素尺寸的FLV视频
/// </summary>
/// <param name="fileName">原视频</param>
/// <param name="outPutPath">输出视频</param>
/// <param name="size">尺寸,不赋值则用原来的</param>
public void VideoFormatToFLV(string fileName,string outPutPath,string size="")
{
//参数:-ab 比特率
if (string.IsNullOrWhiteSpace(size))
{
process.StartInfo.Arguments = " -i " + fileName + " -ab 128 -ar 22050 -qscale 6 -r 29.97 " + outPutPath;
}
else
{
process.StartInfo.Arguments = " -i " + fileName + " -ab 128 -ar 22050 -qscale 6 -r 29.97 -s " +size+ " " + outPutPath;
}
process.Start();
process.WaitForExit();
}
测试代码:
OpenFileDialog open = new OpenFileDialog();
if (!(bool)open.ShowDialog())
{ return false; }
string Name = open.FileName;
HCAsstesManagerment_Wpf.Models.CommonModels.VideoOperation vo = new Models.CommonModels.VideoOperation();
if (vo.IsFinishInitial)
{
vo.GetDWHFromVideo(Name,System.IO.Path.GetFileNameWithoutExtension(Name)+".jpg");
MessageBox.Show(vo.StrDWH);
}
看截图和得到视频特有参数效果:
Win7下原视频信息
程序得到的,格式是长度x帧宽度x帧高度
还有截图:
总结
Ok,写的有点多了,你们随便看看当复习把,需要什么自己找好了,不管怎么养也要保证他的完整性么,多是正常的,或许以后我的能力提升了,懂得精华是什么了把,呵呵。
我测试了我电脑里的视频格式,也算常用格式把,那个程序对大多数格式都支持,像Mp4、wmv、rmvb、avi、flv、mkv、可用,除了qmv这个快播专属不可用。
最近在做个媒体管理系统,以后有什么好的收获还会继续记下的。
最后对自己订个目标,一个星期一篇质量博文。盖个邮戳,2012/10/14