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 ,就可以获得。代码请看下面:

            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

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. PyChram创建虚拟环境

    目录 1. python创建虚拟环境 2. pycharm中添加python虚拟环境 1. python创建虚拟环境 首先要安装virtualenv模块.打开命令行,输入pip install vir ...

  2. Directx11教程40 纹理映射(10)

    原文:Directx11教程40 纹理映射(10)      本章尝试使用纹理行列式,或者说纹理数组,在ps中,使用2个纹理,最终的像素颜色,是光照颜色*纹理1采样颜色*纹理2采样颜色,主要是想达到如 ...

  3. Directx11教程(35) 纹理映射(5)

    原文:Directx11教程(35) 纹理映射(5)     到现在为止,我们的TextureClass初始化函数非常简单,说白了就是一行代码: result = D3DX11CreateShader ...

  4. redis 如何查看版本

    ./redis-cli -h 127.0.0.1 info | grep 'redis_version' redis-server -v

  5. kubernetes1.4新特性:支持Docker新特性

    (一)背景资料 在Kubernetes1.2中这个第三方组件就是go-dockerclient,这是一个GO语言写的docker客户端,支持Dockerremote API,这个项目在https:// ...

  6. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制 代码工程地址: https://gi ...

  7. Libevent:0异步IO简介

    一:异步IO简介 大多数的初级编程者都是从阻塞IO调用开始网络编程的.阻塞(同步)IO调用指的是:调用会一直阻塞,不会返回,直到发生下面两种情况之一.要么操作完成,要么经历相当长的时间,网络协议栈自己 ...

  8. C# —— 枚举

    一.使用枚举的优点 枚举能够使代码更加的清晰,它允许使用描述性的名称表示整数值. 枚举使代码更易于维护,有助于确保给变量指定合法的.期望的值. 枚举使代码更易输入. 二.枚举说明 1.简单枚举 枚举使 ...

  9. java 根据秘钥,对数据进行加解密

    package test; import com.alibaba.fastjson.JSONObject; import sun.misc.BASE64Decoder; import sun.misc ...

  10. 解决移动端1px边框问题的几种方法

    1.边框粗细原因 在移动端下设置border为1px,在某些设备上看比1px粗. 这些由于不同的手机有不同的像素密度.在window对象中有一个devicePixelRatio属性,他可以反应css中 ...