How to overlay a rectangle on an image in WPF

16,228

Solution 1

Put it in a grid, and then put the rectangle in the same row and column. And use a converter to get 80% the size.

XAML:

<Window.Resources>
    <local:RectangleSizeConverter x:Key="RectangleSizeConverter" />
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <Image x:Name="image" Grid.Row="0" Grid.Column="0" Source="C:\on.jpg" />
    <Rectangle Height="{Binding ElementName=image, Path=ActualHeight, Converter={StaticResource RectangleSizeConverter}}" 
               Width="{Binding ElementName=image, Path=ActualWidth, Converter={StaticResource RectangleSizeConverter}}" 
               Fill="Red" Opacity=".5" />
</Grid>

C# (Converter):

public class RectangleSizeConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return System.Convert.ToDouble(value) * .8;
    }

    public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new System.NotImplementedException();
    }

    #endregion
}

Solution 2

Here's a way you can do it with pure XAML using a DrawingBrush to fill the overlying Rectangle only partially:

<Grid>          
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <Image Source="http://sstatic.net/so/img/logo.png" Stretch="None" />
    <Rectangle>
        <Rectangle.Fill>
            <DrawingBrush Viewbox="0,0,1,1" ViewboxUnits="Absolute">
                <DrawingBrush.Drawing>
                    <GeometryDrawing Brush="#66FF0000">
                        <GeometryDrawing.Geometry>
                            <RectangleGeometry Rect="0,0,.9,.9" />
                        </GeometryDrawing.Geometry>
                    </GeometryDrawing>
                </DrawingBrush.Drawing>
            </DrawingBrush>
         </Rectangle.Fill>
     </Rectangle>
</Grid>
Share:
16,228

Related videos on Youtube

adrianm
Author by

adrianm

Updated on June 04, 2022

Comments

  • adrianm
    adrianm about 2 years

    I want to place a static rectangle on top of an image.

    The rectangle should be a percentage of the image size (like 80%) regardless of the image size.

    I have tried to put the image in a Canvas and as a Canvas background but then I can't get the image to fill the surrounding area.

    <Canvas Grid.Row="1" Grid.Column="0">
        <Canvas.Background>
            <ImageBrush ImageSource="{Binding Path=Image1}"/>
        </Canvas.Background>
     </Canvas>
    
    • Drew Marsh
      Drew Marsh over 14 years
      Do you need the image to size dynamically according to the resource or are you setting a fixed size or stretching to fill another area?
    • adrianm
      adrianm over 14 years
      The images are always the same size in pixels but the available space in the view is dynamic.
  • adrianm
    adrianm over 14 years
    Thanks. Didn't know that multiple items in a grid cell will overlap. I'll try it
  • Drew Marsh
    Drew Marsh over 14 years
    There's a simpler way than this (no code necessary), but you didn't answer my question in the comments on your original post.
  • adrianm
    adrianm over 14 years
    Tested and it works fine. Marked it as answer. Prefer to use codebehind instead of IValueConverter for special conversions like this. DependencyPropertyDescriptor.FromProperty(Image.ActualHeight‌​Property, typeof(Image)).AddValueChanged( Image1, (sender, args) => { Image1Rect.Height = (sender as Image).ActualHeight*0.9; });
  • adrianm
    adrianm over 14 years
    That is also a good solution which works fine. I changed the Brush to a Pen to just see the rectangle outline.