Is it possible to select only part of the image (opacity)?

I applied opacity to the image. Here is the code: -

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="DelSilverlightApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="600" d:DesignWidth="800"> <Canvas x:Name="LayoutRoot" Background="White"> <Image Source="Vista.jpg" Height="300" Width="310" Canvas.Left="200" Canvas.Top="200" Opacity="0.8"/> <Grid x:Name="rectToGetXAndY" Canvas.ZIndex="3" Width="254" Height="143" Opacity="0.6" Canvas.Left="223" Canvas.Top="272" /> </Canvas> </UserControl> 

I want only the image area inside the Grid to be set to opacity 1 else, it should remain 0.8. Any ideas how I can do this? This is very important for my application, but for some reason I can not find a solution for it.

Thanks in advance:)

+3
wpf silverlight
source share
3 answers

One way to make this a universal and reusable way is to use OpacityMask with VisualBrush and associate the values ​​in VisualBrush with the image and the grid. This way it will work when the image and grid are moved and resized, etc. VisualBrush can contain a canvas and a rectangle to achieve opacity 0.8 and 1.0. Opacity cannot be used on the canvas, as it will affect the opacity of the rectangle so that Background is executed instead. 0.8 is # CC000000. I used # 50,000,000 to show the effect more clearly.

alt text

Update
Some workarounds were needed for Silverlight, so I downloaded my application for an example here: http://www.mediafire.com/?8pbj5b9t72m5191

WPF version (Silverlight version will also work in WPF)

 <Canvas x:Name="LayoutRoot" Background="White"> <Canvas.Resources> <local:SubtractMultiConverter x:Key="SubtractMultiConverter"/> <local:MaxValueMultiConverter x:Key="MaxValueMultiConverter"/> </Canvas.Resources> <Image Name="image" Source="C:\FG.png" Stretch="Fill" Height="300" Width="310" Canvas.Left="100" Canvas.Top="200"> <Image.OpacityMask> <VisualBrush> <VisualBrush.Visual> <Canvas Background="#50000000" Width="{Binding ElementName=image, Path=ActualWidth}" Height="{Binding ElementName=image, Path=ActualHeight}"> <Rectangle Fill="#FF000000"> <Rectangle.Width> <MultiBinding Converter="{StaticResource MaxValueMultiConverter}"> <Binding ElementName="rectToGetXAndY" Path="ActualWidth"/> <Binding RelativeSource="{RelativeSource self}" Path="(Canvas.Left)"/> <Binding ElementName="image" Path="ActualWidth"/> </MultiBinding> </Rectangle.Width> <Rectangle.Height> <MultiBinding Converter="{StaticResource MaxValueMultiConverter}"> <Binding ElementName="rectToGetXAndY" Path="ActualHeight"/> <Binding RelativeSource="{RelativeSource self}" Path="(Canvas.Top)"/> <Binding ElementName="image" Path="ActualHeight"/> </MultiBinding> </Rectangle.Height> <Canvas.Left> <MultiBinding Converter="{StaticResource SubtractMultiConverter}"> <Binding ElementName="rectToGetXAndY" Path="(Canvas.Left)"/> <Binding ElementName="image" Path="(Canvas.Left)"/> </MultiBinding> </Canvas.Left> <Canvas.Top> <MultiBinding Converter="{StaticResource SubtractMultiConverter}"> <Binding ElementName="rectToGetXAndY" Path="(Canvas.Top)"/> <Binding ElementName="image" Path="(Canvas.Top)"/> </MultiBinding> </Canvas.Top> </Rectangle> </Canvas> </VisualBrush.Visual> </VisualBrush> </Image.OpacityMask> </Image> <Grid x:Name="rectToGetXAndY" Canvas.ZIndex="3" Width="254" Height="143" Canvas.Left="123" Canvas.Top="272" Opacity="0.6"/> </Canvas> 

SubtractMultiConverter

 public class SubtractMultiConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { double value = (double)values[0]; double subtractValue = (double)values[1]; return value - subtractValue; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { return null; } } 

MaxValueMultiConverter

 public class MaxValueMultiConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { double desiredWidth = (double)values[0]; double canvasValue = (double)values[1]; double actualWidth = (double)values[2]; return Math.Min(desiredWidth, actualWidth - canvasValue); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { return null; } } 

Update
I noticed that you want this to work in Silverlight as well. Silverlight does not have MultiBinding, but fortunetely Colin E. has a very good solution for this .
VisualBrush is also missing, but Chris C. has a great solution for this . I had to make some changes to VisualImage to make this work.

The changes were in OnVisualChanged, I added an EventHandler for LayoutUpdated and changed the RenderSize to ActualWidth / ActualHeight

 private FrameworkElement visual = null; private void OnVisualChanged(DependencyPropertyChangedEventArgs args) { //if (args.OldValue != null) ((FrameworkElement)args.OldValue).SizeChanged -= VisualImage_SizeChanged; if (args.NewValue != null) { visual = (FrameworkElement)args.NewValue; visual.SizeChanged += VisualImage_SizeChanged; visual.LayoutUpdated += new EventHandler(visual_LayoutUpdated); PrepareBitmap((int)visual.ActualWidth, (int)visual.ActualHeight); } } void visual_LayoutUpdated(object sender, EventArgs e) { PrepareBitmap((int)visual.ActualWidth, (int)visual.ActualHeight); } 

Silverlight xaml

 <UserControl.Resources> <local:SubtractMultiConverter x:Key="SubtractMultiConverter"/> <local:MaxValueMultiConverter x:Key="MaxValueMultiConverter"/> <Canvas x:Key="testBorder" Background="#50000000" Width="{Binding ElementName=image, Path=ActualWidth}" Height="{Binding ElementName=image, Path=ActualHeight}"> <Rectangle Fill="#FF000000"> <binding:BindingUtil.MultiBindings> <binding:MultiBindings> <binding:MultiBinding TargetProperty="Width" Converter="{StaticResource MaxValueMultiConverter}"> <binding:MultiBinding.Bindings> <binding:BindingCollection> <Binding ElementName="rectToGetXAndY" Path="ActualWidth"/> <Binding RelativeSource="{RelativeSource self}" Path="(Canvas.Left)"/> <Binding ElementName="image" Path="ActualWidth"/> </binding:BindingCollection> </binding:MultiBinding.Bindings> </binding:MultiBinding> <binding:MultiBinding TargetProperty="Height" Converter="{StaticResource MaxValueMultiConverter}"> <binding:MultiBinding.Bindings> <binding:BindingCollection> <Binding ElementName="rectToGetXAndY" Path="ActualHeight"/> <Binding RelativeSource="{RelativeSource self}" Path="(Canvas.Top)"/> <Binding ElementName="image" Path="ActualHeight"/> </binding:BindingCollection> </binding:MultiBinding.Bindings> </binding:MultiBinding> <binding:MultiBinding TargetProperty="Canvas.Left" Converter="{StaticResource SubtractMultiConverter}"> <binding:MultiBinding.Bindings> <binding:BindingCollection> <Binding ElementName="rectToGetXAndY" Path="(Canvas.Left)"/> <Binding ElementName="image" Path="(Canvas.Left)"/> </binding:BindingCollection> </binding:MultiBinding.Bindings> </binding:MultiBinding> <binding:MultiBinding TargetProperty="Canvas.Top" Converter="{StaticResource SubtractMultiConverter}"> <binding:MultiBinding.Bindings> <binding:BindingCollection> <Binding ElementName="rectToGetXAndY" Path="(Canvas.Top)"/> <Binding ElementName="image" Path="(Canvas.Top)"/> </binding:BindingCollection> </binding:MultiBinding.Bindings> </binding:MultiBinding> </binding:MultiBindings> </binding:BindingUtil.MultiBindings> </Rectangle> </Canvas> </UserControl.Resources> <Canvas x:Name="LayoutRoot" Background="White"> <local:VisualImage x:Name="visualImage" Visual="{Binding Source={StaticResource testBorder}}" ImageBrush="{Binding ElementName=brush}"/> <Image Name="image" Source="/GridImageOpacityMask;component/Images/FG.png" Stretch="Fill" Height="300" Width="310" Canvas.Left="200" Canvas.Top="200"> <Image.OpacityMask> <ImageBrush x:Name="brush" /> </Image.OpacityMask> </Image> <Grid x:Name="rectToGetXAndY" Canvas.ZIndex="3" Width="254" Height="143" Opacity="0.6" Canvas.Left="223" Canvas.Top="272"/> </Canvas> 
+2
source share

You can use another Image with the OpacityMask set to VisualBrush , which results in a VisualBrush rectangle like this:

 <Canvas x:Name="LayoutRoot" Background="White"> <Image Source="http://thecybershadow.net/misc/hax.png" Height="300" Width="310" Canvas.Left="200" Canvas.Top="200" Opacity="0.5"/> <Image Source="http://thecybershadow.net/misc/hax.png" Height="300" Width="310" Canvas.Left="200" Canvas.Top="200"> <Image.OpacityMask> <VisualBrush Stretch="None"> <VisualBrush.Visual> <Rectangle Width="254" Height="143" Fill="Black"/> </VisualBrush.Visual> </VisualBrush> </Image.OpacityMask> </Image> <Grid x:Name="rectToGetXAndY" Canvas.ZIndex="3" Width="254" Height="143" Opacity="0.6" Canvas.Left="223" Canvas.Top="272" /> </Canvas> 

and here is another method using Image.Clip :

 <Canvas x:Name="LayoutRoot" Background="White"> <Image Source="http://thecybershadow.net/misc/hax.png" Height="300" Width="310" Canvas.Left="200" Canvas.Top="200" Opacity="0.5"/> <Image Source="http://thecybershadow.net/misc/hax.png" Height="300" Width="310" Canvas.Left="200" Canvas.Top="200"> <Image.Clip> <RectangleGeometry Rect="23,72,254,143"/> </Image.Clip> </Image> <Grid x:Name="rectToGetXAndY" Canvas.ZIndex="3" Width="254" Height="143" Opacity="0.6" Canvas.Left="223" Canvas.Top="272" /> </Canvas> 
+2
source share

Here is a side solution: -

  <Canvas x:Name="LayoutRoot" Background="White"> <Grid x:Name="ImageContainer" Height="300" Width="310" Canvas.Left="200" Canvas.Top="200"> <Image Source="Vista.jpg" /> <Border x:Name="rectToGetXAndY" Background="Transparent" BorderThickness="23, 72, 85, 33" BorderBrush="#99FFFFFF" /> </Grid> </Canvas> 

This provides the same visual appearance of a bright rectangle in a washed image. The visible rectangle can be manipulated by changing the BorderThickness property. Events from this rectangle can be captured on Border , because a transparent background has been added, so it can be dragged, for example. Other content may be added to the internal elements of the Border , for example, a grid of transparent rectangles may provide some calibration options.

The accepted answer here is much more complex compared to, although a more direct answer to your real question.

+1
source share

All Articles