Skip to content

VisualBrush shows letterboxing (black bars) when source and destination have identical size #20638

@browntepheaton

Description

@browntepheaton

Describe the bug

VisualBrush shows letterboxing (black bars) when source and destination have identical size

Summary

When using a VisualBrush to paint a sibling visual that has the same layout size as the destination (same parent, same width and height), Stretch="Uniform" still produces letterboxing (empty strips at top/bottom or left/right). The empty area shows the destination control’s background (e.g. black), so we get unwanted black bars even though the source and target are the same size in the visual tree.

Expected behavior

If the brush’s source visual and the control being painted have identical size (same parent, same bounds), then with Stretch="Uniform" the brush content should fill the destination with no letterboxing — effectively a 1:1 mapping.

Actual behavior

Letterboxing appears (e.g. black bars at top and bottom). This suggests that internally the brush uses a different “content size” or coordinate system when drawing, so the source and destination are not treated as the same size even though they are in layout.

Reproduction

Structure (simplified):

  • A Grid contains two children that both fill the grid (so same size):
    1. Source: A Grid (or Canvas) named FrostedBlurSource with content (e.g. an Image and other controls).
    2. Destination: A Border named FrostedBlurBorder (same size as the grid) whose Background is a VisualBrush with Visual="{Binding #FrostedBlurSource}" and Stretch="Uniform".

So in the layout tree, source and destination have the same width, height, and aspect ratio.

Result: The VisualBrush still leaves empty strips (letterboxing) at top/bottom or left/right. Where the brush does not draw, the Border’s background (e.g. Background="Black") is visible, so we see black bars.

Additional observations:

  • With Stretch="Fill" or Stretch="UniformToFill", the letterboxing disappears but the content is scaled/misaligned and we see ghosting (double image), as if the brush content and the underlying visual are not aligned.
  • With Stretch="None", the brush content does not fill the destination and the effect is largely invisible.

So we have to choose between: correct alignment but letterboxing (Uniform), or no letterboxing but ghosting (Fill/UniformToFill).

Relevant AXAML (minimal repro)

Source and destination are siblings in the same Grid; both fill the grid so they have the same size. The brush uses Stretch="Uniform" and paints the source visual onto the inner Border. Black bars appear at top and bottom.

<Grid x:Name="FrostedBlurGrid" ClipToBounds="True">
    <!-- Source: same size as grid -->
    <Grid x:Name="FrostedBlurSource">
        <Image Source="/Assets/bg_sample.png" Stretch="UniformToFill" />
        <!-- optional: more children for testing -->
    </Grid>

    <!-- Destination: same size as grid; VisualBrush paints FrostedBlurSource -->
    <Border x:Name="FrostedBlurBorder" Background="Black">
        <Border Opacity="0.5">
            <Border.Background>
                <VisualBrush Visual="{Binding #FrostedBlurSource}" Stretch="Uniform" />
            </Border.Background>
            <Border.Effect>
                <BlurEffect Radius="10" />
            </Border.Effect>
        </Border>
    </Border>
</Grid>

With this layout, FrostedBlurSource and FrostedBlurBorder have identical layout bounds, but the VisualBrush still shows letterboxing (black strips at top/bottom).

Environment

  • Avalonia: 11.3.7
  • .NET: 8.0
  • OS: Windows 10 (10.0.19045)

Possible relation

This may be related to Issue #1614 – Visual Brush doesn't work well with DPI Scaling, where the brush content is reported to be skewed or to use a different scale. Here, even at 100% DPI with source and destination having the same layout size, we still get letterboxing, which suggests the internal size or coordinate system used for the brush content does not match the destination size.

Question

Is there a recommended way to get a true 1:1 mapping (no letterboxing, no scaling) when the source visual and the painted control have the same layout size, or is this a known limitation/bug that is tracked elsewhere?

Thank you.

To Reproduce

  1. Create a Grid with two children that both fill the grid (so they have the same size):
    • Source: A Grid named FrostedBlurSource with any content (e.g. an Image).
    • Destination: A Border named FrostedBlurBorder with Background="Black", whose inner content uses a VisualBrush: Visual="{Binding #FrostedBlurSource}" and Stretch="Uniform".
  2. Place that Grid in a window so it gets a non-zero size (e.g. in the main content area).
  3. Run the app and open the window.

Result: Black bars (letterboxing) appear at the top and bottom of the blurred area, even though FrostedBlurSource and FrostedBlurBorder have identical layout bounds in the same parent.

Expected behavior

No response

Avalonia version

11.3.7

OS

Windows

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions