RenderTargetBitmap混淆了WebView缩放

时间:2016-02-10 12:24:14

标签: xaml webview windows-10 win-universal-app rendertargetbitmap

我有一个非常简单的RenderTargetBitmap.RenderAsync重载案例重载WebView缩放。我在MainPage上所拥有的只是一个WebView和一个按钮:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <WebView Source="http://bing.com"></WebView>
    <Button Content="Render me"
            HorizontalAlignment="Right"
            VerticalAlignment="Bottom"
            Click="ButtonBase_OnClick" />
</Grid>

在后面的代码中,只有一个简单的事件处理程序

private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    RenderTargetBitmap rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(this, 1280, 720);
}

这是在RenderAsync调用之前页面的样子:

Before RenderAsync

这就是电话会议后发生的事情:

After RenderAsync

知道为什么以及如何防止这种情况?请注意,只有在我打电话

时才会发生这种情况
await rtb.RenderAsync(this, 1280, 720);

但不是如果我在没有缩放的情况下调用过载

await rtb.RenderAsync(this);

编辑:由于我收到的第一个答案,我想澄清为什么长宽比不是问题,但只是为了证明实际上存在问题。考虑以下情况 - 非常高的DPI屏幕,其中只需要较低分辨率的屏幕截图 - 即使您使用RIGHT比率缩小它,它仍然会混淆WebView。此外,对于我的场景,之后手动调整屏幕大小不是一个选项 - 使用缩放尺寸的RenderAsync重载要快得多,我真的更喜欢使用该方法。

3 个答案:

答案 0 :(得分:1)

非常奇怪的行为...... 我找到了一个非常脏的(!)修复程序。我基本上隐藏并再次显示webview(wv)。

private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    RenderTargetBitmap rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(wv, 1280, 720);
    wv.Visibility = Visibility.Collapsed;
    await Task.Delay(100);
    wv.Visibility = Visibility.Visible;
}

我并不为这个解决方案感到骄傲,而且网页浏览闪现,但至少它不会“被炸毁”......

答案 1 :(得分:1)

这也是一个黑客攻击,但我发现如果你通过WebViewBrush设置另一个控件的内容然后渲染该控件,那么源WebView就没有了得到任何缩放。我修改了你提供的XAML,看起来像这样:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Border x:Name="Target" Width="1280" Height="720" />
    <WebView x:Name="webView"  Source="http://bing.com" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></WebView>

    <Button Content="Render me" Grid.Row="1"
        HorizontalAlignment="Right"
        VerticalAlignment="Bottom"
        Click="ButtonBase_OnClick" />

</Grid>

在您的情况下,您应该选择在Border后面设置WebView控件(但不要更改其Visibility或放置它在窗口边界之外,因为RenderAsync将失败)。然后,在后面的代码中,将目标控件的Background设置为以WebViewBrush为基础的WebView实例:

    private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        WebViewBrush brush = new WebViewBrush();
        brush.SetSource(webView);
        Target.Background = brush;
        Target.InvalidateMeasure();
        Target.InvalidateArrange();

        RenderTargetBitmap rtb = new RenderTargetBitmap();
        await rtb.RenderAsync(Target, 1280, 720);
        var pixels = await rtb.GetPixelsAsync();
    }

您将获得最终图像而不会对来源WebView造成任何问题(但请注意,由于纵横比不匹配,最终图像看起来会失真)。但是,这有一些注意事项,最重要的一点是WebView大小必须与RenderTargetBitmap的大小相匹配,否则您将获得空白区域。

答案 2 :(得分:0)

使用VisibleBounds来获取当前窗口大小,而不是使用固定值。

以下是代码:

private async void pressMe_Click(object sender, RoutedEventArgs e)
{
    var windowBounds = ApplicationView.GetForCurrentView().VisibleBounds;
    RenderTargetBitmap rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(this, (int)windowBounds.Width, (int)windowBounds.Height);
}