Reputation: 25
I want to use RenderTargetBitmap to just capture the visual area in UWP app. But the result is to capture the full element image in canvas that include offscreen's part.
This is my application Image.
This my MainPage.xaml
<Page
x:Class="RenderBitmapTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:RenderBitmapTest"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Width="1600"
Height="900"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Loaded="Page_Loaded"
mc:Ignorable="d">
<Grid>
<Canvas
x:Name="CanvasTest"
Width="1600"
Height="900"
Background="Gray">
<Rectangle
Canvas.Left="-150"
Canvas.Top="-150"
Width="300"
Height="300"
Fill="Green" />
<Rectangle
Canvas.Left="0"
Canvas.Top="150"
Width="300"
Height="300"
Fill="Blue" />
<Image x:Name="Image" Canvas.Left="300" />
</Canvas>
</Grid>
This is RenderTargetBitmap Code.
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
CanvasTest.Measure(new Size(1600, 900));
CanvasTest.Arrange(new Rect(0, 0, 1600, 900));
var rtb = new RenderTargetBitmap();
await rtb.RenderAsync(CanvasTest);
await SaveToBitmapImage(rtb);
//Image.Source = rtb;
}
private async Task SaveToBitmapImage(RenderTargetBitmap rtb)
{
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await storageFolder.CreateFileAsync("test.png", CreationCollisionOption.ReplaceExisting);
var pixels = await rtb.GetPixelsAsync();
using (IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await
BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
byte[] bytes = pixels.ToArray();
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
(uint)rtb.PixelWidth, (uint)rtb.PixelHeight, 96, 96, bytes);
await encoder.FlushAsync();
}
}
The expectation should is to only capture the yellow area.
Could anyone help to solve it?
Thanks, Zack
Upvotes: 1
Views: 175
Reputation: 32775
UWP - Use RenderTargetBitmap and only capture the visual area
The problem is RenderTargetBitmap will render all the content area for Canvas container, so the better way is use Clip to set the RectangleGeometry
and define the outline of the contents of a UIElement. Then RenderTargetBitmap the root Grid to replace CanvasTest
<Grid x:Name="RootGrid">
<Canvas
x:Name="CanvasTest"
Background="Gray">
<Canvas.Clip>
<RectangleGeometry Rect="0,0,1600,900"/>
</Canvas.Clip>
<Rectangle
Canvas.Left="-150"
Canvas.Top="-150"
Width="300"
Height="300"
Fill="Green" />
<Rectangle
Canvas.Left="0"
Canvas.Top="150"
Width="300"
Height="300"
Fill="Blue" />
<Image x:Name="Image" Canvas.Left="300" />
</Canvas>
</Grid>
Code Behind
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
var rtb = new RenderTargetBitmap();
await rtb.RenderAsync(RootGrid);
await SaveToBitmapImage(rtb);
}
Upvotes: 1