有时候需要获得文件或视频的缩略图。

本文提供两个方法,用于获得文件的缩略图和截取视频指定时间的显示图片。

文件缩略图

如果有一个文件需要获得缩略图,可以使用 GetThumbnailAsync 或 GetScaledImageAsThumbnailAsync ,就可以获得。代码请看下面:

            FileOpenPicker openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add(".mp4"); StorageFile file = await openPicker.PickSingleFileAsync();
var thumbnail = await file.GetScaledImageAsThumbnailAsync(ThumbnailMode.VideosView);
BitmapImage bitmapImage = new BitmapImage();
InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
randomAccessStream.Seek(0);
bitmapImage.SetSource(randomAccessStream);
Image.Source = bitmapImage;

可以看到 GetScaledImageAsThumbnailAsync 的参数提供多种方式进行截图,如果知道了文件的类型,就可以使用对应的方式进行显示。需要知道的是 thumbnail 得到的是一个流,就需要把他转换为 BitmapImage 显示。

我接下来获取文件夹内所有文件的缩略图显示出来

首先是界面代码

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="587*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid>
<ListView Margin="10,10,10,10" ItemsSource="{x:Bind Ruqya}" HorizontalAlignment="Stretch">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid ItemWidth="200" Orientation="Horizontal" MaximumRowsOrColumns="5"></WrapGrid>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Ruqya">
<Grid>
<Image Width="100" Height="100" Source="{x:Bind Image}"></Image>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid Grid.Row="1">
<Button Margin="10,10,10,10" Content="确定" Click="Button_OnClick"></Button>
</Grid>
</Grid>

界面是有一个 ListView 和一个 Button ,点击 Button 就会执行从一个文件夹获取所有文件,拿到缩略图。

但是还需要一个类,用于界面显示图片

    public class Ruqya
{
public Ruqya(BitmapImage image)
{
Image = image;
} public BitmapImage Image { get; set; }
}

因为这时的 Image 不会修改,就不需要继承通知

按钮点击的代码,就是核心,需要从文件夹获得文件。


public ObservableCollection<Ruqya> Ruqya { get; set; } = new ObservableCollection<Ruqya>(); private async void Button_OnClick(object sender, RoutedEventArgs e)
{
FolderPicker pick = new FolderPicker();
pick.FileTypeFilter.Add(".txt");
var folder = await pick.PickSingleFolderAsync();
if (folder == null)
{
return;
} Ruqya.Clear(); //获取文件夹所有文件的缩略图 foreach (var temp in await folder.GetFilesAsync())
{
var thumbnail = await temp.GetThumbnailAsync(ThumbnailMode.SingleItem);
BitmapImage bitmapImage = new BitmapImage();
InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
randomAccessStream.Seek(0);
bitmapImage.SetSource(randomAccessStream);
Ruqya.Add(new Ruqya(bitmapImage));
}
}

所有代码就这一点,相信没有看不懂。

接下来告诉大家如何获得视频的小图

视频小图

如果需要获得视频的某一个页面,那么可以使用下面代码,首先是获得视频文件,计算指定时间的视频截图,这时不需要进行播放视频就可以从文件直接获得指定时间的显示图片。

            FileOpenPicker openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add(".mp4"); StorageFile file = await openPicker.PickSingleFileAsync();
var thumbnail = await GetThumbnailAsync(file);
BitmapImage bitmapImage = new BitmapImage();
InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
randomAccessStream.Seek(0);
bitmapImage.SetSource(randomAccessStream);
Image.Source = bitmapImage; public async Task<IInputStream> GetThumbnailAsync(StorageFile file)
{
var mediaClip = await MediaClip.CreateFromFileAsync(file);
var mediaComposition = new MediaComposition();
var time=5000; 获取那一时间的页面
mediaComposition.Clips.Add(mediaClip);
return await mediaComposition.GetThumbnailAsync(
TimeSpan.FromMilliseconds(time), 0, 0, VideoFramePrecision.NearestFrame);
}

这样就可以获得指定时间的页面,因为得到图像是 IInputStream ,所以需要把他转为 bitmapImage ,这样才可以设置为图片。这个方法只需要传入视频的文件,大法支持很多个视频类型,只要有系统解析的,就可以支持,暂时我还不知道他支持的是哪些文件。

接下来就是做下面的软件,在播放视频的时候,拖动进度条,就会显示对应的视频缩略图,如拖到指定时间,就显示这一时间的视频缩略图

首先是界面代码,可以看到界面就一个播放和一个进度条

           <MediaElement x:Name="MediaElement" Margin="10,10,10,10" Stretch="None"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></MediaElement> <Grid VerticalAlignment="Bottom">
<Slider x:Name="Slider" Margin="10,10,10,10" PointerReleased="UIElement_OnPointerReleased" PointerPressed="UIElement_OnPointerReleased"></Slider>
</Grid>

后台代码很多都使用上面的代码,需要知道的有两个代码。第一个是OnPointerReleased 需要添加在构造函数,因为滑动进度会吃了 PointerReleased ,如果不把下面的代码写入,就使用上面界面的代码,可以看到点击的函数不会进去。但是如果加了下面的代码,就可以获得点击的事件。在 UWP 没有区分触摸和鼠标点击,都使用 Pointer 来说是点击结束或者点击。

            Slider.AddHandler(PointerReleasedEvent, new PointerEventHandler(UIElement_OnPointerReleased), true);

需要知道的第二个就是如何进行播放视频,因为上面代码已经从可以选到文件,于是就可以使用从文件播放的方式,让播放器使用文件。代码很简单,对于需要的 MIME 可以忽略,直接给空。如果对他给空,当然要求文件是 mp4 。如果文件是其他的,建议不要给空,播放器解析也许出错。

            MediaElement.SetSource(await file.OpenAsync(FileAccessMode.Read), "");

            如果文件类型不是 mp4 ,请用下面代码
MediaElement.SetSource(await file.OpenAsync(FileAccessMode.Read), file.ContentType);

在点击进度条,就可以获得当前的值,然后计算在视频中的时间,通过这个时间,进行截图。

            var slider = (Slider) sender;
var n = slider.Value / slider.Maximum;
n = MediaElement.NaturalDuration.TimeSpan.TotalMilliseconds * n;

获取视频总时间可以使用 NaturalDuration ,我需要把他转换时间,使用的代码同样很简单

获得需要的时间,就可以使用上面代码进行截图,其中 File 就是刚才选的文件,如果已经播放了,实际还有其它的方法,但是本文说的是文件截图。

            var thumbnail = await GetThumbnailAsync(File, n);
BitmapImage bitmapImage = new BitmapImage();
InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
randomAccessStream.Seek(0);
bitmapImage.SetSource(randomAccessStream);

好像代码已经完成了,但是在哪里显示?为了可以显示,这里使用 Flyout ,给他一个图片控件,用于显示。

            Flyout flyout = new Flyout();
var image = new Image()
{
Width = 100,
Height = 100,
Stretch = Stretch.Fill,
Margin = new Thickness(0)
};
flyout.Content = image;
image.Source = bitmapImage; flyout.ShowAt(slider);

去掉 flyout 背景很简单,我就不说啦,于是所有代码都写在这,不要找我要工程

        private async void UIElement_OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
var slider = (Slider) sender;
var n = slider.Value / slider.Maximum;
n = MediaElement.NaturalDuration.TimeSpan.TotalMilliseconds * n; var thumbnail = await GetThumbnailAsync(File, n);
BitmapImage bitmapImage = new BitmapImage();
InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
randomAccessStream.Seek(0);
bitmapImage.SetSource(randomAccessStream); Flyout flyout = new Flyout();
var image = new Image()
{
Width = 100,
Height = 100,
Stretch = Stretch.Fill,
Margin = new Thickness(0)
};
flyout.Content = image;
image.Source = bitmapImage; flyout.ShowAt(slider);
} private async Task<IInputStream> GetThumbnailAsync(StorageFile file, double time)
{
var mediaClip = await MediaClip.CreateFromFileAsync(file);
var mediaComposition = new MediaComposition();
mediaComposition.Clips.Add(mediaClip);
return await mediaComposition.GetThumbnailAsync(
TimeSpan.FromMilliseconds(time), 0, 0, VideoFramePrecision.NearestFrame);
}

感谢 李继龙

参见:https://stackoverflow.com/a/37314446/6116637


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

win10 uwp 获得缩略图的更多相关文章

  1. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

  2. Win10 UWP开发系列:实现Master/Detail布局

    在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...

  3. Win10 UWP开发实现Bing翻译

    微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...

  4. Win10/UWP开发—使用Cortana语音与App后台Service交互

    上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...

  5. 【Win10 UWP】后台任务与动态磁贴

    动态磁贴(Live Tile)是WP系统的大亮点之一,一直以来受到广大用户的喜爱.这一讲主要研究如何在UWP应用里通过后台任务添加和使用动态磁贴功能. 从WP7到Win8,再到Win10 UWP,磁贴 ...

  6. 【Win10 UWP】URI Scheme(一):Windows Store协议的解析和使用

    协议是Windows Phone和Windows Store应用的一个重要特点,可以做到在不同应用之间进行互相呼起调用.小小协议,学问大着呢.我打算写几篇关于协议在UWP中使用的文章. 这一讲的主要对 ...

  7. 【Win10 UWP】QQ SDK(二):SDK的回调处理

    上一讲,我们介绍了QQ SDK的使用方法,请看<[Win10 UWP]QQ SDK(一):SDK基本使用方法> 一. 回调的基本形式 从前面的介绍中我们知道,我们的应用和QQ客户端之间需要 ...

  8. Win10 UWP应用发布流程

    简介 Win10 UWP应用作为和Win8.1 UAP应用不同的一种新应用形式,其上传至Windows应用商店的流程也有了一些改变. 这篇博文记录了我们发布一款Win10 UWP应用的基本流程,希望为 ...

  9. 【Win10 UWP】QQ SDK(一):SDK基本使用方法

    每当开发一个应用需要社交分享的应用时,总是心里咯噔一下:到底什么时候分享能加上QQ和微信?除了WP8.0版本的微信SDK,官方似乎从未正面发布过适应时代发展的QQ SDK,就连后台,也没有一个可以创建 ...

随机推荐

  1. 团队作业8——第二次项目冲刺(Beta阶段)5.21

    1.当天站立式会议照片 会议内容: 本次会议为第三次会议 本次会议在陆大楼2楼召开,本次会议内容: ①:检查总结第二次任务完成情况 ②:布置第三次任务的详细分工 ③:规定完成时间是在第四次任务之前 ④ ...

  2. 201521123111《Java程序设计》第7周学习总结

    1. 本章学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 线性表,栈,队列,哈希表是常用的数据结构 在java.util包中有这些数据结构的实现类.比如:List接口,实现类Arra ...

  3. 201521123060 《Java程序设计》第7周学习总结

    1. 本周学习总结 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 答:contains方法调用indexOf方法,遍历遍历内部用于保存数据的e ...

  4. 201521123119《Java程序设计》第1周学习总结

    1.本周学习总结    1.Java语言是一种多用途的语言.并发的语言.以类为基础,面向对象的语言. 2.Java比C++更加方便,有辅助输入,编写速度大大加快. 3.Java根据应用领域不同,区分为 ...

  5. JAVA课程设计+购物车 个人博客

    1. 团队课程设计博客链接 2.个人负责模块或任务说明 将数据库中已经存在的商品取出,用表格显示到页面中. 实现在商品页面的购买,直接弹出消息框,输出价格,实现购买. 实现在商品页面进行添加购物车,并 ...

  6. 201521123080《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前 ...

  7. 201521123045 《JAVA程序设计》 第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...

  8. 201521123019 《java程序设计》 第14周学习总结

    1. 本章学习总结 2. 书面作业 Q1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 在自己建立的数据库上执行常见SQL语句(截图) ...

  9. 201521123075 《Java程序设计》第13周学习总结

    1. 本周学习总结 协议 网络中为了进行数据交换(通信)而建立的规则.标准或约定(=语义+语法+规则),比如http, ftp等 IP层协议(Internet Protocol) Internet上的 ...

  10. javascript:12种JavaScript MVC框架之比较

    Gordon L. Hempton是西雅图的一位黑客和设计师,他花费了几个月的时间研究和比较了12种流行的JavaScript MVC框架,并在博客中总结了每种框架的优缺点,最终的结果是,Ember. ...