7.2.3 使用RenderTargetBitmap类生成图片
RenderTargetBitmap類可以將可視化對象轉(zhuǎn)換為位圖,也就是說它可以將任意的UIElement以位圖的形式呈現(xiàn)。那么我們在實(shí)際的編程中通常會利用RenderTargetBitmap類來對UI界面進(jìn)行截圖操作,比如把程序的界面或者某個控件的外觀生成一張圖片。
??? 使用RenderTargetBitmap類生成圖片一般有兩種用途,一種是直接把生成的圖片在當(dāng)前的頁面上進(jìn)行展示,還有一種用途是把生成的圖片當(dāng)作文件存儲起來,或者通過某種分享方式把圖片文件分享出去。那么第二種用途的編程實(shí)現(xiàn)肯定是在第一種的編程實(shí)現(xiàn)的基礎(chǔ)上來實(shí)現(xiàn)的,所以我們首先看一下第一種情況的實(shí)現(xiàn),如何把截圖在當(dāng)前的界面上展示。
??? 使用RenderTargetBitmap類生成圖片的操作主要是依賴于RenderTargetBitmap類的RenderAsync方法。RenderAsync方法有兩個重載:RenderAsync(UIElement) 和 RenderAsync(UIElement, Int32, Int32),可在后者處指定要與源可視化樹的自然大小不同的所需圖像源尺寸,沒有設(shè)置則是按照元素的原始大小生成圖片。RenderAsync方法被設(shè)計為異步方法,因此無法保證與UI源進(jìn)行精確的框架同步,但大多數(shù)情況下都足夠及時。由于 RenderTargetBitmap是ImageSource的子類,因此,可以將其用作Image元素或 ImageBrush畫筆的圖像源。
下面給出生成程序截圖的示例:通過點(diǎn)擊屏幕來生成當(dāng)前程序界面的截圖,并把截圖用Image控件展示出來,每次的點(diǎn)擊都產(chǎn)生一個最新的截圖并進(jìn)行展示。 ??? 代碼清單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="我的應(yīng)用程序" FontSize="20" /> <TextBlock Text="點(diǎn)擊截屏" 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) { // 創(chuàng)建一個RenderTargetBitmap對象,對界面中的Grid控件root生成圖片 RenderTargetBitmap bitmap = new RenderTargetBitmap(); await bitmap.RenderAsync(root); // 把圖片展現(xiàn)出來 img.Source = bitmap; }7.2.4 存儲生成的圖片文件
??? 在上文我們講解了如何把程序界面截圖出來放到Image控件上展示,那么我們接下來將繼續(xù)介紹如何把截圖出來的圖片保存到程序存儲里面。在我們調(diào)用RenderAsync方法的時候會初始化RenderTargetBitmap類的對象,但是RenderTargetBitmap類的對象本身并不能作為圖片來進(jìn)行存儲,要生成圖片文件需要獲取到圖片的二進(jìn)制數(shù)據(jù)。如果你想要獲取 DataTransferManager 操作(例如共享協(xié)定交換)的圖像,或想要使用 Windows.Graphics.Imaging API 將效果應(yīng)用到圖像上或?qū)D像進(jìn)行轉(zhuǎn)碼,那么就需要用到像素數(shù)據(jù)。如果你想訪問RenderTargetBitmap的Pixels數(shù)據(jù),你需要在用RenderAsync這個方法將UIElement定義為 RenderTargetBitmap后,再調(diào)用RenderTargetBitmap的GetPixelsAsync方法來獲得其Pixels數(shù)據(jù)。該方法返回的是一個IBuffer類型,里面存儲的是二進(jìn)制的位圖數(shù)。這個IBuffer可以轉(zhuǎn)換為一個Byte數(shù)組,數(shù)組里面的數(shù)據(jù)是以BGRA8格式存儲的。
??? 以下代碼示例如何從一個RenderTargetBitmap對象中獲得以byte數(shù)組類型存儲的像素數(shù)。需要特別注意的是IBuffer實(shí)例調(diào)用的ToArray方法是一個擴(kuò)展方法,你需要在你的項(xiàng)目中加入System.Runtime.InteropServices.WindowsRuntime這個命名空間。
??? var bitmap = new RenderTargetBitmap();
??? await bitmap.RenderAsync(elementToRender);
?? ?IBuffer pixelBuffer = await bitmap.GetPixelsAsync();
?? ?byte[] pixels = pixelBuffer.ToArray();
??? 那么在獲取到了圖像的二進(jìn)制數(shù)據(jù)之后,如果要把二進(jìn)制的數(shù)據(jù)生成圖片文件,需要使用到BitmapEncoder類。BitmapEncoder類包含創(chuàng)建、編輯和保存圖像的各種方法。創(chuàng)建圖片文件首先需要調(diào)用BitmapEncoder類CreateAsync方法,來使用文件的流來創(chuàng)建一個BitmapEncoder對象,然后再使用BitmapEncoder類的SetPixelData設(shè)置圖像有關(guān)幀的像素數(shù)據(jù)。SetPixelData的方法參數(shù)如下:
??? SetPixelData(BitmapPixelFormat pixelFormat, BitmapAlphaMode alphaMode, uint width, uint height, double dpiX, double dpiY, byte[] pixels)
??? 其中,pixelFormat表示像素數(shù)據(jù)的像素格式;alphaMode表示像素數(shù)據(jù)的alpha模式;width表示像素數(shù)據(jù)的寬度(以像素為單位);height表示像素數(shù)據(jù)的高度(以像素為單位);dpiX表示像素數(shù)據(jù)的水平分辨率(以每英寸點(diǎn)數(shù)為單位);dpiY表示像素數(shù)據(jù)的垂直分辨率(以每英寸點(diǎn)數(shù)為單位);pixels表示像素數(shù)據(jù)。此方法是同步的,因?yàn)橹钡秸{(diào)用 FlushAsync、GoToNextFrameAsync 或 GoToNextFrameAsync(IIterable(IKeyValuePair)) 才會提交數(shù)據(jù)。此方法將所有像素數(shù)據(jù)視為sRGB 顏色空間中的像素數(shù)據(jù)。
下面給出保存截圖文件的示例:先使用RenderTargetBitmap類生成程序界面的截圖,然后再將截圖的二進(jìn)制數(shù)據(jù)生成圖片文件存儲到程序存儲中。 ??? 代碼清單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); // 獲取圖像的二進(jìn)制數(shù)據(jù) var pixelBuffer = await renderTargetBitmap.GetPixelsAsync(); // 創(chuàng)建程序文件存儲 IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder; IStorageFile saveFile = await applicationFolder.CreateFileAsync("snapshot.png", CreationCollisionOption.OpenIfExists); // 把圖片的二進(jìn)制數(shù)據(jù)寫入文件存儲 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; }轉(zhuǎn)載于:https://www.cnblogs.com/LY-Byfalt/p/4859224.html
總結(jié)
以上是生活随笔為你收集整理的7.2.3 使用RenderTargetBitmap类生成图片的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 滴滴回应高额抽成 司机收入占乘客应付总
- 下一篇: 行数溢出隐藏