在 C# 中获取视频文件的缩略图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15702031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get thumbnail image of video file in C#
提问by meer
I want to display thumbnails for videos listed on my site, I want to fetch a single frame from a video (from a particular time) and display them as thumbnails.
我想显示我网站上列出的视频的缩略图,我想从视频(来自特定时间)中获取单个帧并将它们显示为缩略图。
I have try this http://ramcrishna.blogspot.com/2008/09/playing-videos-like-youtube-and.htmlbut is not working.
我试过这个http://ramcrishna.blogspot.com/2008/09/playing-videos-like-youtube-and.html但没有用。
Is that possible using .NET C#?
可以使用 .NET C# 吗?
采纳答案by markyd13
You can programmatically execute FFmpegto generate a thumbnail image file. Then open the image file to use it however you wish.
您可以以编程方式执行FFmpeg以生成缩略图图像文件。然后打开图像文件以随意使用它。
Here is some sample code:
下面是一些示例代码:
public static Bitmap GetThumbnail(string video, string thumbnail)
{
var cmd = "ffmpeg -itsoffset -1 -i " + '"' + video + '"' + " -vcodec mjpeg -vframes 1 -an -f rawvideo -s 320x240 " + '"' + thumbnail + '"';
var startInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = "/C " + cmd
};
var process = new Process
{
StartInfo = startInfo
};
process.Start();
process.WaitForExit(5000);
return LoadImage(thumbnail);
}
static Bitmap LoadImage(string path)
{
var ms = new MemoryStream(File.ReadAllBytes(path));
return (Bitmap)Image.FromStream(ms);
}
回答by Vitaliy Fedorchenko
FFMpeg is a right tool that can be used to extract video frame at some position. You can invoke ffmpeg.exe as mentioned above or just use existing .NET wrapper (like Video converter for .NET(it's free) to get thumbnail with just one line of code:
FFMpeg 是一个正确的工具,可以用来提取某个位置的视频帧。您可以如上所述调用 ffmpeg.exe 或仅使用现有的 .NET 包装器(如 .NET 的视频转换器(它是免费的)),只需一行代码即可获取缩略图:
var ffMpeg = new NReco.VideoConverter.FFMpegConverter();
ffMpeg.GetVideoThumbnail(pathToVideoFile, thumbJpegStream,5);
回答by Debendra Dash
[HttpPost]
[Route("UploadImages")]
public HttpResponseMessage Post()
{
HttpResponseMessage response = new HttpResponseMessage();
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count > 0)
{
var docfiles = new List<string>();
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath1 = HttpContext.Current.Server.MapPath("~/ImgFolder/" + postedFile.FileName);
Stream strm = postedFile.InputStream;
CreateThumbnail(strm, postedFile.FileName);
Compressimage(strm, filePath1, postedFile.FileName);
}
response = Request.CreateResponse(HttpStatusCode.Created, docfiles);
}
else
{
response = Request.CreateResponse(HttpStatusCode.BadRequest);
}
return response;
}
public static void **CreateThumbnail**(Stream sourcePath, string filename)
{
Image image = Image.FromStream(sourcePath);
Image thumb = image.GetThumbnailImage(120, 120, () => false, IntPtr.Zero);
var filePath1 = HttpContext.Current.Server.MapPath("~/Thumbnail/" + filename);
thumb.Save(filePath1 + filename);
}
public static void Compressimage(Stream sourcePath, string targetPath, String filename)
{
try
{
using (var image = Image.FromStream(sourcePath))
{
float maxHeight = 900.0f;
float maxWidth = 900.0f;
int newWidth;
int newHeight;
string extension;
Bitmap originalBMP = new Bitmap(sourcePath);
int originalWidth = originalBMP.Width;
int originalHeight = originalBMP.Height;
if (originalWidth > maxWidth || originalHeight > maxHeight)
{
// To preserve the aspect ratio
float ratioX = (float)maxWidth / (float)originalWidth;
float ratioY = (float)maxHeight / (float)originalHeight;
float ratio = Math.Min(ratioX, ratioY);
newWidth = (int)(originalWidth * ratio);
newHeight = (int)(originalHeight * ratio);
}
else
{
newWidth = (int)originalWidth;
newHeight = (int)originalHeight;
}
Bitmap bitMAP1 = new Bitmap(originalBMP, newWidth, newHeight);
Graphics imgGraph = Graphics.FromImage(bitMAP1);
extension = Path.GetExtension(targetPath);
if (extension == ".png" || extension == ".gif")
{
imgGraph.SmoothingMode = SmoothingMode.AntiAlias;
imgGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
imgGraph.DrawImage(originalBMP, 0, 0, newWidth, newHeight);
bitMAP1.Save(targetPath, image.RawFormat);
bitMAP1.Dispose();
imgGraph.Dispose();
originalBMP.Dispose();
}
else if (extension == ".jpg")
{
imgGraph.SmoothingMode = SmoothingMode.AntiAlias;
imgGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
imgGraph.DrawImage(originalBMP, 0, 0, newWidth, newHeight);
ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
Encoder myEncoder = Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
myEncoderParameters.Param[0] = myEncoderParameter;
bitMAP1.Save(targetPath, jpgEncoder, myEncoderParameters);
bitMAP1.Dispose();
imgGraph.Dispose();
originalBMP.Dispose();
}
}
}
catch (Exception)
{
throw;
}
}
public static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
回答by viewbevy
Xabe.FFmpeg- free, open source and cross-platform library. Provides fluent API to FFmpeg. Generating thumbnail from video in Xabe.F
Xabe.FFmpeg- 免费、开源和跨平台的库。为 FFmpeg 提供流畅的 API。从 Xabe.F 中的视频生成缩略图
string output = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + FileExtensions.Png);
IConversionResult result = await Conversion.Snapshot(Resources.Mp4WithAudio, output, TimeSpan.FromSeconds(0))
.Start();
It requires FFmpeg executables like in other answer but you can download it by
它需要像其他答案一样的 FFmpeg 可执行文件,但您可以通过以下方式下载它
FFmpeg.GetLatestVersion();
Full documentation available here - Xabe.FFmpeg Documentation
此处提供完整文档 - Xabe.FFmpeg 文档
回答by Omid Soleiman
string fileName = Guid.NewGuid().GetString() + ".jpg";
fileName = fileName.Replace("-", "");
var ffMpeg = new NReco.VideoConverter.FFMpegConverter();
ffMpeg.GetVideoThumbnail("VideoAddress", fileName, 2);
string sourcePath = HttpContext.Current.Server.MapPath(fileName);
string targetPath = HttpContext.Current.Server.MapPath("/video/");
string destFile = System.IO.Path.Combine(targetPath, fileName);
System.IO.File.Move(sourcePath, destFile);
回答by Ken
For people don't want to use FFMpeg as its trouble in Commercial software. I have an old solution here:
因为人们不想在商业软件中使用 FFMpeg 作为它的麻烦。我这里有一个旧的解决方案:
ShellFile shellFile = ShellFile.FromFilePath(VideoFileName);
Bitmap bm = shellFile.Thumbnail.Bitmap;
Then you will get a Bitmap object that can be used in drawing. If you want a file, just do:
然后你会得到一个可以用于绘图的 Bitmap 对象。如果你想要一个文件,只需执行以下操作:
bm.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
if you want a BitmapImage that you can use it in Xaml binding. just transfer the Bitmap to BitmapImage. Here is an example:
如果您想要一个可以在 Xaml 绑定中使用它的 BitmapImage。只需将 Bitmap 传输到 BitmapImage。下面是一个例子:
public static BitmapImage ConvertBitmapToBitmapImage(Bitmap bitmap)
{
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
BitmapImage image = new BitmapImage();
image.BeginInit();
ms.Seek(0, SeekOrigin.Begin);
image.StreamSource = ms;
image.EndInit();
return image;
}