[深刻淺出WP8.1(Runtime)]生成圖片和存儲生成的圖片文件

7.2.3 使用RenderTargetBitmap類生成圖片

    RenderTargetBitmap類能夠將可視化對象轉換爲位圖,也就是說它能夠將任意的UIElement以位圖的形式呈現。那麼咱們在實際的編程中一般會利用RenderTargetBitmap類來對UI界面進行截圖操做,好比把程序的界面或者某個控件的外觀生成一張圖片。html

    使用RenderTargetBitmap類生成圖片通常有兩種用途,一種是直接把生成的圖片在當前的頁面上進行展現,還有一種用途是把生成的圖片看成文件存儲起來,或者經過某種分享方式把圖片文件分享出去。那麼第二種用途的編程實現確定是在第一種的編程實現的基礎上來實現的,因此咱們首先看一下第一種狀況的實現,如何把截圖在當前的界面上展現。編程

    使用RenderTargetBitmap類生成圖片的操做主要是依賴於RenderTargetBitmap類的RenderAsync方法。RenderAsync方法有兩個重載:RenderAsync(UIElement) 和 RenderAsync(UIElement, Int32, Int32),可在後者處指定要與源可視化樹的天然大小不一樣的所需圖像源尺寸,沒有設置則是按照元素的原始大小生成圖片。RenderAsync方法被設計爲異步方法,所以沒法保證與UI源進行精確的框架同步,但大多數狀況下都足夠及時。因爲 RenderTargetBitmap是ImageSource的子類,所以,能夠將其用做Image元素或 ImageBrush畫筆的圖像源。數組

下面給出生成程序截圖的示例:經過點擊屏幕來生成當前程序界面的截圖,並把截圖用Image控件展現出來,每次的點擊都產生一個最新的截圖並進行展現。
    代碼清單7-9:生成程序截圖(源代碼:第7章\Examples_7_9)微信

MainPage.xaml文件主要代碼
------------------------------------------------------------------------------------------------------------------
    <!--註冊PointerReleased 事件用於捕獲屏幕的單擊操做,並在時間處理程序中生成圖片-->
    <Grid x:Name="root" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
          PointerReleased="Grid_PointerReleased">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,35,0,28">
            <TextBlock Text="個人應用程序" FontSize="20"  />
            <TextBlock Text="點擊截屏" FontSize="60" />
        </StackPanel>
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" >
            <!--該圖片控件用於展現截圖圖片效果-->
            <Image x:Name="img" />
        </Grid>
    </Grid>
MainPage.xaml.cs文件主要代碼
------------------------------------------------------------------------------------------------------------------
    // 指針釋放的事件處理程序
    private async void Grid_PointerReleased(object sender, PointerRoutedEventArgs e)
    {
        // 建立一個RenderTargetBitmap對象,對界面中的Grid控件root生成圖片
        RenderTargetBitmap bitmap = new RenderTargetBitmap();
        await bitmap.RenderAsync(root);
        // 把圖片展示出來
        img.Source = bitmap;
    }

7.2.4 存儲生成的圖片文件

    在上文咱們講解了如何把程序界面截圖出來放到Image控件上展現,那麼咱們接下來將繼續介紹如何把截圖出來的圖片保存到程序存儲裏面。在咱們調用RenderAsync方法的時候會初始化RenderTargetBitmap類的對象,可是RenderTargetBitmap類的對象自己並不能做爲圖片來進行存儲,要生成圖片文件須要獲取到圖片的二進制數據。若是你想要獲取 DataTransferManager 操做(例如共享協定交換)的圖像,或想要使用 Windows.Graphics.Imaging API 將效果應用到圖像上或對圖像進行轉碼,那麼就須要用到像素數據。若是你想訪問RenderTargetBitmap的Pixels數據,你須要在用RenderAsync這個方法將UIElement定義爲 RenderTargetBitmap後,再調用RenderTargetBitmap的GetPixelsAsync方法來得到其Pixels數據。該方法返回的是一個IBuffer類型,裏面存儲的是二進制的位圖數。這個IBuffer能夠轉換爲一個Byte數組,數組裏面的數據是以BGRA8格式存儲的。app

    如下代碼示例如何從一個RenderTargetBitmap對象中得到以byte數組類型存儲的像素數。須要特別注意的是IBuffer實例調用的ToArray方法是一個擴展方法,你須要在你的項目中加入System.Runtime.InteropServices.WindowsRuntime這個命名空間。框架

    var bitmap = new RenderTargetBitmap();異步

    await bitmap.RenderAsync(elementToRender);async

    IBuffer pixelBuffer = await bitmap.GetPixelsAsync();ui

    byte[] pixels = pixelBuffer.ToArray();spa

    那麼在獲取到了圖像的二進制數據以後,若是要把二進制的數據生成圖片文件,須要使用到BitmapEncoder類。BitmapEncoder類包含建立、編輯和保存圖像的各類方法。建立圖片文件首先須要調用BitmapEncoder類CreateAsync方法,來使用文件的流來建立一個BitmapEncoder對象,而後再使用BitmapEncoder類的SetPixelData設置圖像有關幀的像素數據。SetPixelData的方法參數以下:

    SetPixelData(BitmapPixelFormat pixelFormat, BitmapAlphaMode alphaMode, uint width, uint height, double dpiX, double dpiY, byte[] pixels)

    其中,pixelFormat表示像素數據的像素格式;alphaMode表示像素數據的alpha模式;width表示像素數據的寬度(以像素爲單位);height表示像素數據的高度(以像素爲單位);dpiX表示像素數據的水平分辨率(以每英寸點數爲單位);dpiY表示像素數據的垂直分辨率(以每英寸點數爲單位);pixels表示像素數據。此方法是同步的,由於直到調用 FlushAsync、GoToNextFrameAsync 或 GoToNextFrameAsync(IIterable(IKeyValuePair)) 纔會提交數據。此方法將全部像素數據視爲sRGB 顏色空間中的像素數據。

下面給出保存截圖文件的示例:先使用RenderTargetBitmap類生成程序界面的截圖,而後再將截圖的二進制數據生成圖片文件存儲到程序存儲中。
    代碼清單7-10保存截圖文件(源代碼:第7章\Examples_7_10)

MainPage.xaml文件主要代碼
------------------------------------------------------------------------------------------------------------------
    <Grid x:Name="root" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        ……省略若干代碼
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel>
                <Button x:Name="bt_save" Content="存儲生成的圖片" Click="bt_save_Click"></Button>
                <Button x:Name="bt_show" Content="展現存儲的圖片" Click="bt_show_Click"></Button>
                <ScrollViewer BorderBrush="Red" BorderThickness="2" Height="350">
                    <Image x:Name="img" />
                </ScrollViewer>
            </StackPanel>
        </Grid>
    </Grid>
MainPage.xaml.cs文件主要代碼
------------------------------------------------------------------------------------------------------------------
    // 按鈕事件生成圖片並保存到程序的存儲裏面
    private async void bt_save_Click(object sender, RoutedEventArgs e)
    {
        // 生成RenderTargetBitmap對象
        RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
        await renderTargetBitmap.RenderAsync(root);
        // 獲取圖像的二進制數據
        var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
        // 建立程序文件存儲
        IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
        IStorageFile saveFile = await applicationFolder.CreateFileAsync("snapshot.png", CreationCollisionOption.OpenIfExists);
        // 把圖片的二進制數據寫入文件存儲
        using (var fileStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);
            encoder.SetPixelData(
                BitmapPixelFormat.Bgra8,
                BitmapAlphaMode.Ignore,
                (uint)renderTargetBitmap.PixelWidth,
                (uint)renderTargetBitmap.PixelHeight,
                DisplayInformation.GetForCurrentView().LogicalDpi,
                DisplayInformation.GetForCurrentView().LogicalDpi,
                pixelBuffer.ToArray());
            await encoder.FlushAsync();
        }
    }
    // 展現程序存儲圖片的按鈕事件
    private void bt_show_Click(object sender, RoutedEventArgs e)
    {
        // 「ms-appdata:///local」表示是程序存儲的根目錄
        BitmapImage bitmapImage = new BitmapImage(new Uri("ms-appdata:///local/snapshot.png", UriKind.Absolute));
        img.Source = bitmapImage;
    }

本文來源於《深刻淺出Windows Phone 8.1 應用開發》

WP8.1 Runtime文章列表:http://www.cnblogs.com/linzheng/p/3998037.html

源代碼下載:http://vdisk.weibo.com/s/zt_pyrfNHb99O

歡迎關注個人微博@WP林政   微信公衆號:wp開發(號:wpkaifa)

WP8.1技術交流羣:372552293

相關文章
相關標籤/搜索