2

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 を呼び出す前のページは次のようになります。

RenderAsync の前

そして、これは呼び出し後に何が起こるかです:

RenderAsync の後

これを防ぐ理由と方法はありますか?私が電話した場合にのみ発生することに注意してください

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

しかし、スケーリングなしでオーバーロードを呼び出す場合はそうではありません

await rtb.RenderAsync(this);

編集:私が受け取った最初の回答により、ここでアスペクト比が問題ではない理由を明確にしたいと思いましたが、実際に問題があることを証明する目的のみに役立ちます。次のシナリオを考えてみましょう - 低解像度のスクリーンショットだけが必要な非常に高い DPI 画面 - 正しい比率で縮小しても、WebView は台無しになります。また、私のシナリオでは、後でスクリーンショットを手動でサイズ変更することはできません。スケーリングされた寸法を使用した RenderAsync オーバーロードははるかに高速であり、その方法を使用することを本当に好みます。

4

3 に答える 3

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(ただし、コントロールを変更したり、ウィンドウの境界の外に置いたりしないでください。失敗します)。次に、コード ビハインドで、ターゲット コントロールの を、をフィードする のインスタンスに設定します。VisibilityRenderAsyncBackgroundWebViewBrushWebView

    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ことです。

于 2016-02-11T21:12:28.297 に答える
1

非常に奇妙な動作...これに対する非常に汚い(!)修正が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;
}

私はこのソリューションを誇りに思っておらず、ウェブビューが点滅しますが、少なくとも「爆破」されていません...

于 2016-02-11T19:10:47.100 に答える
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);
}
于 2016-02-10T20:54:50.197 に答える