新時尚Windows8開發(29):多媒體捕捉(進階篇)

來源:互聯網
上載者:User

這今說的這個所謂進階篇,是相對而言的,就是比上一節說的內容稍稍靈活了一些,不過我想我們在做應用的時候,也很少這麼進階去搞,你要說專業的拍攝程式,那壓根用不著你做,人家裝置供應商就已經開發了,就像我買的Dell的產品,人家就已經提供了一個很強大的拍攝程式了。

 

不過呢,瞭解一下,研究一下還是有意義的。這個“進階”內容便是和MediaCapture類有關,主要就是它,你看它的人生閱曆不淺,N多個方法,當然,這些方法我們總的來說就可能用到三個,即預覽的,拍照片的,錄製視頻的,是啊你想攝像就這幾個用途而已。可能有人說,那視訊交談呢?視訊交談不就動態錄製視頻唄。

 

所以,很多事情,我們不必須弄得太複雜,就像今天這例子一樣,很簡單,不過也許是可以說明其應用價值的。

那麼,我們今天玩什麼呢?弄一個定時拍攝好不?這還有點意思的。

 

1、建立項目,不會的回家複習。

2、XAML頁面不用多東西,既然要拍東西,那得能夠預覽網路攝影機中的內容,這樣方便拍攝,所以,先弄一個CaptureElement,這是專門在UI上顯晃網路攝影機預覽用的;另外,我們要顯示定時拍到的照片,所以,要一個ListView控制項;要進行相關操作,需要扔幾個按鈕。

<Page    x:Class="App1.MainPage"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:local="using:App1"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    mc:Ignorable="d">    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">        <Grid.RowDefinitions>            <RowDefinition Height="*"/>            <RowDefinition Height="auto"/>        </Grid.RowDefinitions>        <CaptureElement x:Name="ce" Grid.Row="0" Margin="13"/>        <Grid Grid.Row="1">            <Grid.ColumnDefinitions>                <ColumnDefinition Width="*"/>                <ColumnDefinition Width="auto"/>            </Grid.ColumnDefinitions>            <ListView x:Name="lv" Grid.Column="0" Margin="3,2,3,3" SelectionMode="None" Height="150">                <ListView.ItemTemplate>                    <DataTemplate>                        <Image Width="120" Height="120" Stretch="Uniform" Source="{Binding}"/>                    </DataTemplate>                </ListView.ItemTemplate>                <ListView.ItemsPanel>                    <ItemsPanelTemplate>                        <VirtualizingStackPanel Orientation="Horizontal"/>                    </ItemsPanelTemplate>                </ListView.ItemsPanel>            </ListView>            <StackPanel Grid.Column="1" Margin="10">                <Button Content="開始" Click="onStart" x:Name="btnStart"/>                <Button Content="停止" Click="onStop" x:Name="btnStop" IsEnabled="False"/>            </StackPanel>        </Grid>    </Grid></Page>

3、要定時拍攝,自然要有個計時器,這個有,在Windows.System.Threading命名空間下,其名曰:ThreadPoolTimer,我們將用它來計時。

先引入以下命名空間:

using Windows.System.Threading;using System.Collections.ObjectModel;using Windows.UI.Xaml.Media.Imaging;using Windows.Media.Capture;using Windows.Media.MediaProperties;using Windows.Storage.Streams;

在MainPage類中定義以下成員:

    public sealed partial class MainPage : Page    {        ObservableCollection<BitmapImage> images = null;        MediaCapture myCapture = null;        ThreadPoolTimer myTimer = null;

在MainPage的建構函式裡面幫它們化妝一下。

        public  MainPage()        {            this.InitializeComponent();            this.myCapture = new MediaCapture();            this.images = new ObservableCollection<BitmapImage>();            this.lv.ItemsSource = images;        }

我們希望在導航到頁面時就開啟網路攝影機並開始預覽,所以,在OnNavigatedTo方法中要做點手腳。

        protected override async void OnNavigatedTo(NavigationEventArgs e)        {            await this.myCapture.InitializeAsync();            this.ce.Source = myCapture;            await this.myCapture.StartPreviewAsync();        }

ThreadPoolTimer類是通過調用一個靜態方法CreatePeriodicTimer來建立計時器的,而我們看到這個方法的兩個重載中,參數都需要一個委託,這個委託要綁定一個方法,當計時器到了執行任務的時間,就會調用這個委託,從而調用指定的方法。

所以我們要先定義好這個處理方法:

        private async void timerHandler(ThreadPoolTimer t)        {            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>                {                    IRandomAccessStream stream = new InMemoryRandomAccessStream();                    await myCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreatePng(), stream);                    // 在向流寫入資料時,已經把指標移到結尾處                    // 所以在初始化映像是要先把指標移回開始位置                    stream.Seek(0);                    BitmapImage bmpimg = new BitmapImage();                    bmpimg.SetSource(stream);                    this.images.Add(bmpimg);                });        }

注意,在調用CreatePeriodicTimer方法成功返回後就馬上開始計時了,如果要取消計時,就調用Cancel方法。

 

4、這時候,我們需要的組件代碼基本可以了,下面就處理那兩個控制開始拍攝和停止拍攝的按鈕的Click事件。

        private void onStop(object sender, RoutedEventArgs e)        {            if (this.myTimer != null)            {                this.myTimer.Cancel(); //取消            }            btnStop.IsEnabled = false;            btnStart.IsEnabled = true;        }        private void onStart(object sender, RoutedEventArgs e)        {            this.images.Clear();             // 開始計時            this.myTimer = ThreadPoolTimer.CreatePeriodicTimer(timerHandler, TimeSpan.FromSeconds(5));            btnStart.IsEnabled = false;            btnStop.IsEnabled = true;        }

 

完整的代碼如下:

using System;using System.Collections.Generic;using System.IO;using System.Linq;using Windows.Foundation;using Windows.Foundation.Collections;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Controls.Primitives;using Windows.UI.Xaml.Data;using Windows.UI.Xaml.Input;using Windows.UI.Xaml.Media;using Windows.UI.Xaml.Navigation;using Windows.System.Threading;using System.Collections.ObjectModel;using Windows.UI.Xaml.Media.Imaging;using Windows.Media.Capture;using Windows.Media.MediaProperties;using Windows.Storage.Streams;// “空白頁”項目範本在 http://go.microsoft.com/fwlink/?LinkId=234238 上有介紹namespace App1{    /// <summary>    /// 可用於自身或導航至 Frame 內部的空白頁。    /// </summary>    public sealed partial class MainPage : Page    {        ObservableCollection<BitmapImage> images = null;        MediaCapture myCapture = null;        ThreadPoolTimer myTimer = null;        public  MainPage()        {            this.InitializeComponent();            this.myCapture = new MediaCapture();            this.images = new ObservableCollection<BitmapImage>();            this.lv.ItemsSource = images;        }        /// <summary>        /// 在此頁將要在 Frame 中顯示時進行調用。        /// </summary>        /// <param name="e">描述如何訪問此頁的事件數目據。Parameter        /// 屬性通常用於配置頁。</param>        protected override async void OnNavigatedTo(NavigationEventArgs e)        {            await this.myCapture.InitializeAsync();            this.ce.Source = myCapture;            await this.myCapture.StartPreviewAsync();        }        private async void timerHandler(ThreadPoolTimer t)        {            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>                {                    IRandomAccessStream stream = new InMemoryRandomAccessStream();                    await myCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreatePng(), stream);                    // 在向流寫入資料時,已經把指標移到結尾處                    // 所以在初始化映像是要先把指標移回開始位置                    stream.Seek(0);                    BitmapImage bmpimg = new BitmapImage();                    bmpimg.SetSource(stream);                    this.images.Add(bmpimg);                });        }        private void onStop(object sender, RoutedEventArgs e)        {            if (this.myTimer != null)            {                this.myTimer.Cancel(); //取消            }            btnStop.IsEnabled = false;            btnStart.IsEnabled = true;        }        private void onStart(object sender, RoutedEventArgs e)        {            this.images.Clear();             // 開始計時            this.myTimer = ThreadPoolTimer.CreatePeriodicTimer(timerHandler, TimeSpan.FromSeconds(5));            btnStart.IsEnabled = false;            btnStop.IsEnabled = true;        }    }}

5、開啟資訊清單檔,切換到“功能”選項卡,同時勾選“麥克風”和“網路攝像機”,並儲存。

 

6、運行應用程式,等預覽開始後,點擊[開始] 按鈕,程式就會每隔5秒鐘(因為代碼中指定的是秒)拍攝一張照片,並顯示在ListView中。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.