我已将不透明度应用于图像。这是代码: -
<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>
我希望只有Grid内部图像的区域应设置为1的不透明度,否则它应保持为0.8。任何想法我怎么能这样做?这对我的应用程序非常重要,但不知怎的,我找不到解决方案。
提前致谢:)
答案 0 :(得分:2)
您可以使用Image
设置为OpacityMask
的其他VisualBrush
,从而产生如下剪裁矩形:
<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>
这是使用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>
答案 1 :(得分:2)
以通用和可重用的方式执行此操作的一种方法是使用带有VisualBrush的OpacityMask,并将VisualBrush中的值绑定到Image和Grid。这样,当图像和网格四处移动并改变大小等时,它将起作用.VisualBrush可以包含Canvas和Rectangle来实现0.8和1.0不透明度。不能在Canvas上使用不透明度,因为它会影响矩形的不透明度,因此背景将会改变。 0.8等于#CC000000。我使用#50000000来更清楚地显示效果。
<强>更新强>
Silverlight版本需要一些解决方法,所以我在这里上传了我的示例应用程序:http://www.mediafire.com/?8pbj5b9t72m5191
WPF版本(Silverlight版本也适用于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;
}
}
<强>更新强>
我注意到你也想在Silverlight中使用它。 Silverlight没有MultiBinding,但很幸运的是Colin E.有一个very nice solution for this
VisualBrush也缺失了,但Chris C.有一个nice solution to that。我必须对VisualImage进行一些更改才能使其工作。
更改在OnVisualChanged中,我为LayoutUpdated添加了一个EventHandler,并将RenderSize更改为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 :(得分:1)
这是一个横向解决方案: -
<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>
这提供了褪色图像中充满活力的矩形的相同视觉外观。可以通过修改BorderThickness
属性来操纵明显的矩形。此矩形中的事件可能会被Border
捕获,因为已添加透明背景,因此可以拖动它。其他内容可以添加到Border
的内部,例如透明矩形网格可以提供一些尺寸特征。
通过比较,这里接受的答案要复杂得多,尽管对你的实际问题有更直接的答案。