title author date CreateTime categories
win10 uwp 获得缩略图
lindexi
2018-08-10 19:16:51 +0800
2018-2-13 17:23:3 +0800
Win10 UWP

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

文件缩略图

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

  1. FileOpenPicker openPicker = new FileOpenPicker();
  2. openPicker.FileTypeFilter.Add(".mp4");
  3.  
  4. StorageFile file = await openPicker.PickSingleFileAsync();
  5. var thumbnail = await file.GetScaledImageAsThumbnailAsync(ThumbnailMode.VideosView);
  6. BitmapImage bitmapImage = new BitmapImage();
  7. InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
  8. await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
  9. randomAccessStream.Seek(0);
  10. bitmapImage.SetSource(randomAccessStream);
  11. Image.Source = bitmapImage;

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

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

首先是界面代码

  1. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  2. <Grid.RowDefinitions>
  3. <RowDefinition Height="587*"/>
  4. <RowDefinition Height="auto"/>
  5. </Grid.RowDefinitions>
  6. <Grid>
  7. <ListView Margin="10,10,10,10" ItemsSource="{x:Bind Ruqya}" HorizontalAlignment="Stretch">
  8. <ListView.ItemsPanel>
  9. <ItemsPanelTemplate>
  10. <WrapGrid ItemWidth="200" Orientation="Horizontal" MaximumRowsOrColumns="5"></WrapGrid>
  11. </ItemsPanelTemplate>
  12. </ListView.ItemsPanel>
  13. <ListView.ItemTemplate>
  14. <DataTemplate x:DataType="local:Ruqya">
  15. <Grid>
  16. <Image Width="100" Height="100" Source="{x:Bind Image}"></Image>
  17. </Grid>
  18. </DataTemplate>
  19. </ListView.ItemTemplate>
  20. </ListView>
  21. </Grid>
  22. <Grid Grid.Row="1">
  23. <Button Margin="10,10,10,10" Content="确定" Click="Button_OnClick"></Button>
  24. </Grid>
  25. </Grid>

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

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

  1. public class Ruqya
  2. {
  3. public Ruqya(BitmapImage image)
  4. {
  5. Image = image;
  6. }
  7.  
  8. public BitmapImage Image { get; set; }
  9. }

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

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

  1. public ObservableCollection<Ruqya> Ruqya { get; set; } = new ObservableCollection<Ruqya>();
  2.  
  3. private async void Button_OnClick(object sender, RoutedEventArgs e)
  4. {
  5. FolderPicker pick = new FolderPicker();
  6. pick.FileTypeFilter.Add(".txt");
  7. var folder = await pick.PickSingleFolderAsync();
  8. if (folder == null)
  9. {
  10. return;
  11. }
  12.  
  13. Ruqya.Clear();
  14.  
  15. //获取文件夹所有文件的缩略图
  16.  
  17. foreach (var temp in await folder.GetFilesAsync())
  18. {
  19. var thumbnail = await temp.GetThumbnailAsync(ThumbnailMode.SingleItem);
  20. BitmapImage bitmapImage = new BitmapImage();
  21. InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
  22. await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
  23. randomAccessStream.Seek(0);
  24. bitmapImage.SetSource(randomAccessStream);
  25. Ruqya.Add(new Ruqya(bitmapImage));
  26. }
  27. }

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

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

视频小图

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

  1. FileOpenPicker openPicker = new FileOpenPicker();
  2. openPicker.FileTypeFilter.Add(".mp4");
  3.  
  4. StorageFile file = await openPicker.PickSingleFileAsync();
  5. var thumbnail = await GetThumbnailAsync(file);
  6. BitmapImage bitmapImage = new BitmapImage();
  7. InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
  8. await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
  9. randomAccessStream.Seek(0);
  10. bitmapImage.SetSource(randomAccessStream);
  11. Image.Source = bitmapImage;
  12.  
  13. public async Task<IInputStream> GetThumbnailAsync(StorageFile file)
  14. {
  15. var mediaClip = await MediaClip.CreateFromFileAsync(file);
  16. var mediaComposition = new MediaComposition();
  17. var time=5000; 获取那一时间的页面
  18. mediaComposition.Clips.Add(mediaClip);
  19. return await mediaComposition.GetThumbnailAsync(
  20. TimeSpan.FromMilliseconds(time), 0, 0, VideoFramePrecision.NearestFrame);
  21. }

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

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

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

  1. <MediaElement x:Name="MediaElement" Margin="10,10,10,10" Stretch="None"
  2. HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></MediaElement>
  3.  
  4. <Grid VerticalAlignment="Bottom">
  5. <Slider x:Name="Slider" Margin="10,10,10,10" PointerReleased="UIElement_OnPointerReleased" PointerPressed="UIElement_OnPointerReleased"></Slider>
  6. </Grid>

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

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

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

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

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

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

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

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

  1. var thumbnail = await GetThumbnailAsync(File, n);
  2. BitmapImage bitmapImage = new BitmapImage();
  3. InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
  4. await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
  5. randomAccessStream.Seek(0);
  6. bitmapImage.SetSource(randomAccessStream);

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

  1. Flyout flyout = new Flyout();
  2. var image = new Image()
  3. {
  4. Width = 100,
  5. Height = 100,
  6. Stretch = Stretch.Fill,
  7. Margin = new Thickness(0)
  8. };
  9. flyout.Content = image;
  10. image.Source = bitmapImage;
  11.  
  12. flyout.ShowAt(slider);

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

  1. private async void UIElement_OnPointerReleased(object sender, PointerRoutedEventArgs e)
  2. {
  3. var slider = (Slider) sender;
  4. var n = slider.Value / slider.Maximum;
  5. n = MediaElement.NaturalDuration.TimeSpan.TotalMilliseconds * n;
  6.  
  7. var thumbnail = await GetThumbnailAsync(File, n);
  8. BitmapImage bitmapImage = new BitmapImage();
  9. InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
  10. await RandomAccessStream.CopyAsync(thumbnail, randomAccessStream);
  11. randomAccessStream.Seek(0);
  12. bitmapImage.SetSource(randomAccessStream);
  13.  
  14. Flyout flyout = new Flyout();
  15. var image = new Image()
  16. {
  17. Width = 100,
  18. Height = 100,
  19. Stretch = Stretch.Fill,
  20. Margin = new Thickness(0)
  21. };
  22. flyout.Content = image;
  23. image.Source = bitmapImage;
  24.  
  25. flyout.ShowAt(slider);
  26. }
  27.  
  28. private async Task<IInputStream> GetThumbnailAsync(StorageFile file, double time)
  29. {
  30. var mediaClip = await MediaClip.CreateFromFileAsync(file);
  31. var mediaComposition = new MediaComposition();
  32. mediaComposition.Clips.Add(mediaClip);
  33. return await mediaComposition.GetThumbnailAsync(
  34. TimeSpan.FromMilliseconds(time), 0, 0, VideoFramePrecision.NearestFrame);
  35. }

感谢 李继龙

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

2018-8-10-win10-uwp-获得缩略图的更多相关文章

  1. win10 uwp 获得缩略图

    有时候需要获得文件或视频的缩略图. 本文提供两个方法,用于获得文件的缩略图和截取视频指定时间的显示图片. 文件缩略图 如果有一个文件需要获得缩略图,可以使用 GetThumbnailAsync 或 G ...

  2. win10 uwp 使用 Microsoft.Graph 发送邮件

    在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...

  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应用发布流程

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

  6. win10 uwp 列表模板选择器

    本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...

  7. win10 uwp 获得元素绝对坐标

    有时候需要获得一个元素,相对窗口的坐标,在修改他的位置可以使用. 那么 UWP 如何获得元素坐标? 我提供了一个方法,可以获得元素的坐标. 首先需要获得元素,如果没有获得元素,那么如何得到他的坐标? ...

  8. win10 uwp 毛玻璃

    毛玻璃在UWP很简单,不会和WPF那样伤性能. 本文告诉大家,如何在 UWP 使用 win2d 做毛玻璃. 毛玻璃可以使用 win2D 方法,也可以使用 Compositor . 使用 win2d 得 ...

  9. win10 uwp 读取保存WriteableBitmap 、BitmapImage

    我们在UWP,经常使用的图片,数据结构就是 BitmapImage 和 WriteableBitmap.关于 BitmapImage 和 WriteableBitmap 区别,我就不在这里说.主要说的 ...

  10. 【广告】win10 uwp 水印图床 含代码

    本文主要是广告我的软件. 图床可以加速大家写博客上传图片的时间,通过简化我们的操作来得到加速. 在写博客的时候,我们发现,我们需要上传一张图片,需要先打开图片,然后选择本地图片,然后上传. 但是我经常 ...

随机推荐

  1. Leetcode806.Number of Lines To Write String写字符串需要的行数

    我们要把给定的字符串 S 从左到右写到每一行上,每一行的最大宽度为100个单位,如果我们在写某个字母的时候会使这行超过了100 个单位,那么我们应该把这个字母写到下一行.我们给定了一个数组 width ...

  2. ef core 随记

    EntityTypeConfiguration internal class OrderEntityTypeConfiguration : IEntityTypeConfiguration<Or ...

  3. Java练习 SDUT-3849_分数四则运算

    分数四则运算 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 编写程序,实现两个分数的加减法 Input 输入包含多行数 ...

  4. find 使用搜集

    find:-atime +n/-n:表示访问或执行时间大于或小于n天的文件-ctime +n/-n:表示写入.更改inode属性的时间大于或小于n天的文件-mtime +n/-n:表示写入时间大于或小 ...

  5. OpenCV 新手教程 之环境配置 + 图片匹配 matchTemplate

    1.什么是OpenCV OpenCV的全称是:Open Source Computer Vision Library. OpenCV是一个基于(开源)发行的跨平台计算机视觉库,能够执行在Linux.W ...

  6. jQuery 无刷新评论

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. jquery attr()和prop()方法的区别

    $('').attr()返回的是html对象 $('').prop()返回的是DOM对象 attr(): attr() 方法设置或返回被选元素的属性和值. 当该方法用于返回属性值,则返回第一个匹配元素 ...

  8. oracle选择最有效率的表名顺序

    ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条 ...

  9. SDUT-3331_数据结构实验之链表八:Farey序列

    数据结构实验之链表八:Farey序列 Time Limit: 10 ms Memory Limit: 600 KiB Problem Description Farey序列是一个这样的序列:其第一级序 ...

  10. c++中单引号和双引号的区别

    在C++中单引号表示字符,双引号表示字符串. 例如 :在定义一个数组的时候string a [5]={"nihao","henhao","good&q ...