win10 uwp 获得缩略图
有时候需要获得文件或视频的缩略图。
本文提供两个方法,用于获得文件的缩略图和截取视频指定时间的显示图片。
文件缩略图
如果有一个文件需要获得缩略图,可以使用 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 获得缩略图的更多相关文章
- Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App
安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...
- Win10 UWP开发系列:实现Master/Detail布局
在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...
- Win10 UWP开发实现Bing翻译
微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...
- Win10/UWP开发—使用Cortana语音与App后台Service交互
上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...
- 【Win10 UWP】后台任务与动态磁贴
动态磁贴(Live Tile)是WP系统的大亮点之一,一直以来受到广大用户的喜爱.这一讲主要研究如何在UWP应用里通过后台任务添加和使用动态磁贴功能. 从WP7到Win8,再到Win10 UWP,磁贴 ...
- 【Win10 UWP】URI Scheme(一):Windows Store协议的解析和使用
协议是Windows Phone和Windows Store应用的一个重要特点,可以做到在不同应用之间进行互相呼起调用.小小协议,学问大着呢.我打算写几篇关于协议在UWP中使用的文章. 这一讲的主要对 ...
- 【Win10 UWP】QQ SDK(二):SDK的回调处理
上一讲,我们介绍了QQ SDK的使用方法,请看<[Win10 UWP]QQ SDK(一):SDK基本使用方法> 一. 回调的基本形式 从前面的介绍中我们知道,我们的应用和QQ客户端之间需要 ...
- Win10 UWP应用发布流程
简介 Win10 UWP应用作为和Win8.1 UAP应用不同的一种新应用形式,其上传至Windows应用商店的流程也有了一些改变. 这篇博文记录了我们发布一款Win10 UWP应用的基本流程,希望为 ...
- 【Win10 UWP】QQ SDK(一):SDK基本使用方法
每当开发一个应用需要社交分享的应用时,总是心里咯噔一下:到底什么时候分享能加上QQ和微信?除了WP8.0版本的微信SDK,官方似乎从未正面发布过适应时代发展的QQ SDK,就连后台,也没有一个可以创建 ...
随机推荐
- Matlab生成.exe可执行程序
由于在教学过程中需要演示Matlab程序,而教学机又未安装Matlab程序,因此有必要将Matlab程序生成.exe可执行程序,便于直接执行. 在Matlab中提供了Complier,可直接使用. ( ...
- 团队作业4——第一次项目冲刺(Alpha版本)4th day
一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 计时功能已经完成,然后24点的代码如何在游戏界面与界面组件联系上正在进行. 四.困难与问题 1.在安卓框架与java代码的结合 ...
- 201521123076 《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...
- 201521123118《java与程序设计》第14周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...
- [PHP源码阅读]number_format函数
上次讲到PHP是如何解析大整数的,一笔带过了number_format的处理,再详细阅读该函数的源码,以下是小分析. 函数原型 string number_format ( float $number ...
- MapReduce极简教程
一个有趣的例子 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃? MapReduce方法则是: 给在座的所有玩家中分配这摞牌 让每个玩家数自己手中的牌有几张是黑桃,然后 ...
- day20<IO流>
IO流(IO流概述及其分类) IO流(FileInputStream) IO流(read()方法返回值为什么是int) IO流(FileOutputStream) IO流(FileOutputStre ...
- shell二位数组——终端字符下降动画
猜想:Shell支持关联数组,可以利用关联数组模拟二维数组. [验证猜想] #!/bin/bash array[1,1]=1 array[2,1]=2 array[3,1]=3 for i in `s ...
- css常用属性2
1 浮动和清除浮动 在上篇的第十一节--定位中说道: CSS 有三种基本的定位机制:普通流.浮动和绝对定位. 普通流和绝对定位已经说完,接下来就是浮动了. 什么是浮动? CSS 的 Float(浮动 ...
- Angular - Templates(模板)
点击查看AngularJS系列目录 转载请注明出处:http://www.cnblogs.com/leosx/ 在Angular中,模板是一个包含了Angular特定元素和属性的HTML.Angula ...