I have a canvas in my Window and occasionally I want to take snapshots of the content.
I have the following method to do so:
private PngBitmapEncoder captureVisual(Visual v)
{
RenderTargetBitmap bmp = new RenderTargetBitmap(546, 410, 120, 96, PixelFormats.Pbgra32);
bmp.Render(v);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Interlace = Png开发者_JS百科InterlaceOption.On;
encoder.Frames.Add(BitmapFrame.Create(bmp));
return encoder;
}
I call this method with the following method which is called by a press button action(the idea is to add the picture to another canvas which will display the "photo":
private void take_photo(Object sender, RoutedEventArgs e)
{
System.Windows.Controls.Image photoImg = new System.Windows.Controls.Image();
BitmapEncoder enc = captureVisual(videoCanvas);
photoImg.Source = enc.Frames[0];
photoCanvas.Children.Add(photoImg);
}
The problem:
When I take the photo the origin of the photo/bitmap is not the origin of the canvas but the origin of the window. So the Canvas appears in the bitmap translated towards bottom/right in the same position as it is in relation to the top-left corner of the window. I have no idea why this is happening.
As an example see the pic below: There is white space to the top left and the actual content is translated to the bottom right. The origin should be where the actual image is located. I will try to put around a border to make it easier to visualize the problem(sorry I don't know how to put a border around the image if anyone knows please tell me or edit it yourself. Thanks).
Thanks to the comment of dowhilefor I got the answer from this link:
The problem is WPF implicitly adds the margins of the Canvas in relation to the parent container. In my case the parent container was a Grid and I didn't define any margins, the canvas was filling a specific cell. Nevertheless this somehow gets incorporated in the bitmap.
The solution, wrap the Canvas around another Canvas. That's stupid but it works. IMHO this is a bug in WPF:
<Canvas
Name="outerCanvas"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Row="1" Grid.Column="1">
<Canvas
Name="videoCanvas"
Canvas.Left="0"
Canvas.Top="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
/>
</Canvas>
精彩评论