【问题标题】:RenderTargetBitmap messes up the WebView scalingRenderTargetBitmap 搞乱了 WebView 缩放
【发布时间】:2016-02-12 05:12:28
【问题描述】:

我有一个非常简单的 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 之前页面的样子:

这就是通话后发生的事情:

知道为什么以及如何防止这种情况吗?请注意,只有当我调用时才会发生这种情况

await rtb.RenderAsync(this, 1280, 720);

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

await rtb.RenderAsync(this);

编辑:由于我收到的第一个答案,我想澄清为什么纵横比不是这里的问题,而只是为了证明确实存在问题。考虑以下场景 - 非常高的 DPI 屏幕,只需要较低分辨率的屏幕截图 - 即使您使用 RIGHT 比例缩小它,它仍然会弄乱 WebView。此外,对于我的场景,事后手动调整屏幕截图的大小不是一种选择 - 具有缩放尺寸的 RenderAsync 重载要快得多,我真的更喜欢使用该方法。

【问题讨论】:

  • 当然这是一个错误,唯一的解决方法是一个闪烁的小东西 MainWebView.Visibility = Visibility.Collapsed;等待 Task.Delay(10); MainWebView.Visibility = Visibility.Visible;
  • @JuanPabloGarciaCoello 谢谢,您和 Pieter 都提出了类似的解决方案。 :)
  • 为什么不能手动调整位图大小?如果您是从前台(不是XamlRenderingBackgroundTask)执行此操作,您可以使用 Win2D 等 GPU 加速方法来非常快地执行此操作。
  • WinComposition 团队正在从 UIElement 制作一个新的 get 画笔(这就是我的解释),但我认为在 Build 之前我们不会有消息,所以每年我们都会对所有 API 感到震惊消息。可能那时也解决了那个bug。
  • 我还记得这个 WebViewBrush,我从来没有用过它,有趣的是它在 Windows Phone 不支持的 cmets 中说,内容不会被捕获(截图我明白)你试过这个吗确定吗?

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


【解决方案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;
}

我对这个解决方案并不感到自豪,并且 webview 会闪烁,但至少它不再“炸毁”了......

【讨论】:

  • 感谢 Pieter,这似乎确实有所作为,但不幸的是,对于我的情况,这确实不是一个解决方案。 :( 赞成,但希望会有其他想法......
【解决方案2】:

这也是一个小技巧,但我发现如果您通过 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 设置为以WebView 为基础的WebViewBrush 的实例:

    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 的大小相匹配,否则您将获得空白区域。

【讨论】:

    【解决方案3】:

    不使用固定值,而是使用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);
    }
    

    【讨论】:

    • 是的,我知道这一点,这就是为什么我故意使用随机尺寸来展示效果。另一个原因是,如果您尝试在高 DPI 屏幕上缩小图像,也会出现此问题。而且,即使结果图像被弄乱了(我希望如果比例错误),我也不希望 WebView 内容被弄乱。
    • 以为您正在寻找快速解决方案。你说的很对;即使纵横比不匹配,它也不应该影响视图。似乎RenderAsync() 在渲染之前缩放视图本身。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 2017-07-12
    • 1970-01-01
    • 2012-02-11
    • 2017-12-10
    • 2016-03-28
    相关资源
    最近更新 更多