Question

I'm using PixelShader effects for an image.

  1. Image effects for adjusting Contrast, Brightness, CMY & RGB using SLIDERS
  2. Blend mode Image effects which are predefined & loaded in a combo box and users can select their own choice.

This is the Image element and the image effect for adjusting Contrast, Brightness, CMY & RGB are applied in this way.

<Viewbox  x:Name="cImage" Stretch="Uniform"  Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Margin="0" >
    <Image x:Name="ViewedPhoto"   Source="IMG_0071.jpg" 
    Stretch="None" VerticalAlignment="Top" HorizontalAlignment="Left"  Margin="0,5,0,95" >
        <Image.Effect>
            <l:BrightContrastEffect 
            Brightness="{Binding Value, ElementName=bVal}"
            Contrast="{Binding Value, ElementName=cVal}"
            Red="{Binding Value, ElementName=rVal}"
            Green="{Binding Value, ElementName=gVal}"
            Blue="{Binding Value, ElementName=blVal}"
        />

        </Image.Effect>
    </Image>
</Viewbox>

Slider for brightness:

    <Slider Maximum="1" Minimum="-1"  x:Name="bVal"  TickFrequency="1" TickPlacement="BottomRight"  />
<StackPanel Orientation="Horizontal">
                <TextBox Text="{Binding Value, ElementName=bVal, UpdateSourceTrigger=PropertyChanged}"  TextAlignment="Right" Width="30"  Height="10" Margin="0" RenderTransformOrigin="-1.167,0.423" Visibility="Hidden"/>
</StackPanel>

From the above when i move the sliders for adjusting Contrast, Brightness, CMY & RGB, it's working.

I apply predefined Blend mode image effects using comboBox.

<ComboBox x:Name="cColorEffects"  SelectionChanged="cColorEffects_SelectionChanged" />

To show the different effects i call ViewedPhoto.Effect = null; at first & then apply the selected effect.

if (cColorEffects.SelectedIndex == 0)
{
    ViewedPhoto.Effect = null;
    ViewedPhoto.Effect = new AverageEffect();
}
if (cColorEffects.SelectedIndex == 1)
{
    ViewedPhoto.Effect = null;
    ViewedPhoto.Effect = new ColorBurnEffect();
}

Problems:

  1. I'm calling another image effects through comboBox so the image effects for adjusting Contrast, Brightness, CMY & RGB are not working.

  2. I'm using ViewedPhoto.Effect = null; the image effects for adjusting Contrast, Brightness, CMY & RGB are not working.

I want to make the sliders working for adjusting Contrast, Brightness, CMY & RGB and apply the blend mode image effects simultaneously. How can i fix this? Or Give me an idea to fix this?

EDIT:

I have been thinking I could do make the slider binding pro-grammatically and the image effect. Does it make sense? if it's good; How can i apply this?

<Image x:Name="ViewedPhoto"   >
    <Image.Effect>
        <l:BrightContrastEffect 
        Brightness="{Binding Value, ElementName=bVal}"
        Contrast="{Binding Value, ElementName=cVal}"
        Red="{Binding Value, ElementName=rVal}"
        Green="{Binding Value, ElementName=gVal}"
        Blue="{Binding Value, ElementName=blVal}"
    />

    </Image.Effect>
</Image>

<Slider Maximum="1" Minimum="-1"  x:Name="bVal"  TickFrequency="1" TickPlacement="BottomRight"  />
<StackPanel Orientation="Horizontal">
    <TextBox Text="{Binding Value, ElementName=bVal, UpdateSourceTrigger=PropertyChanged}"  Visibility="Hidden"/>
    <Button x:Name="bReset" Content="R" Height="10" Width="30" Margin="35,0,0,0" Click="bReset_Click"/>
</StackPanel>

<Slider Maximum="1" Minimum="-1" x:Name="cVal" TickFrequency="1" TickPlacement="BottomRight" />
<StackPanel Orientation="Horizontal">
    <TextBox Text="{Binding Value, ElementName=cVal, UpdateSourceTrigger=PropertyChanged}"    Visibility="Hidden" />
    <Button x:Name="cReset" Content="R" Height="10" Width="30" Margin="35,0,0,0" Click="cReset_Click"/>
</StackPanel>

Additional info with codes:

 public class BlendModeEffect : ShaderEffect
    {
        public BlendModeEffect()
        {
            UpdateShaderValue(InputProperty);
            UpdateShaderValue(TextureProperty);
        }

        public Brush Input
        {
            get { return (Brush)GetValue(InputProperty); }
            set { SetValue(InputProperty, value); }
        }
        public static readonly DependencyProperty InputProperty =
            ShaderEffect.RegisterPixelShaderSamplerProperty
            (
                "Input",
                typeof(BlendModeEffect),
                0
            );

        public Brush Texture
        {
            get { return (Brush)GetValue(TextureProperty); }
            set { SetValue(TextureProperty, value); }
        }
        public static readonly DependencyProperty TextureProperty =
            ShaderEffect.RegisterPixelShaderSamplerProperty
            (
                "Texture",
                typeof(BlendModeEffect),
                1
            );
    }
//Contrast, Brightness, CMY & RGB Effect
  public class BrightContrastEffect : ShaderEffect
    {
        private static PixelShader m_shader =
            new PixelShader() { UriSource = MakePackUri("bricon.ps") };

        public BrightContrastEffect()
        {


            PixelShader = m_shader;
            UpdateShaderValue(InputProperty);
            UpdateShaderValue(BrightnessProperty);
            UpdateShaderValue(ContrastProperty);
            UpdateShaderValue(RedProperty);
            UpdateShaderValue(GreenProperty);
            UpdateShaderValue(BlueProperty);

        }

        // MakePackUri is a utility method for computing a pack uri 
        // for the given resource.  
        public static Uri MakePackUri(string relativeFile)
        {
            Assembly a = typeof(BrightContrastEffect).Assembly;

            // Extract the short name. 
            string assemblyShortName = a.ToString().Split(',')[0];

            string uriString = "pack://application:,,,/" +
                assemblyShortName +
                ";component/" +
                relativeFile;

            return new Uri(uriString);
        }

        public Brush Input
        {
            get { return (Brush)GetValue(InputProperty); }
            set { SetValue(InputProperty, value); }
        }

        public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(BrightContrastEffect), 0);

        public float Brightness
        {
            get { return (float)GetValue(BrightnessProperty); }
            set { SetValue(BrightnessProperty, value); }
        }

        public static readonly DependencyProperty BrightnessProperty = DependencyProperty.Register("Brightness", typeof(double), typeof(BrightContrastEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(0)));

        public float Contrast
        {
            get { return (float)GetValue(ContrastProperty); }
            set { SetValue(ContrastProperty, value); }
        }

        public static readonly DependencyProperty ContrastProperty = DependencyProperty.Register("Contrast", typeof(double), typeof(BrightContrastEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(1)));


        public float Red
        {
            get { return (float)GetValue(RedProperty); }
            set { SetValue(RedProperty, value); }
        }

        public static readonly DependencyProperty RedProperty = DependencyProperty.Register("Red", typeof(double), typeof(BrightContrastEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(2)));

        public float Green
        {
            get { return (float)GetValue(GreenProperty); }
            set { SetValue(RedProperty, value); }
        }

        public static readonly DependencyProperty GreenProperty = DependencyProperty.Register("Green", typeof(double), typeof(BrightContrastEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(3)));

        public float Blue
        {
            get { return (float)GetValue(BlueProperty); }
            set { SetValue(BlueProperty, value); }
        }

        public static readonly DependencyProperty BlueProperty = DependencyProperty.Register("Blue", typeof(double), typeof(BrightContrastEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(4)));

        //private static PixelShader m_shader = new PixelShader() { UriSource = new Uri(@"pack://application:,,,/CustomPixelRender;component/bricon.ps") };

    }

//Average Blend Mode Effect
 public class AverageEffect : BlendModeEffect
    {
        public static Uri MakePackUri(string relativeFile)
        {
            Assembly a = typeof(ColorBurnEffect).Assembly;

            // Extract the short name. 
            string assemblyShortName = a.ToString().Split(',')[0];

            string uriString = "pack://application:,,,/" +
                assemblyShortName +
                ";component/" +
                relativeFile;

            return new Uri(uriString);
        }
        static AverageEffect()
        {
            _pixelShader.UriSource = MakePackUri("AverageEffect.ps");
        }

        public AverageEffect()
        {
            this.PixelShader = _pixelShader;
        }

        private static PixelShader _pixelShader = new PixelShader();
    }

//ColorBurn Effect
  public class ColorDodgeEffect : BlendModeEffect
    {
        public static Uri MakePackUri(string relativeFile)
        {
            Assembly a = typeof(ColorBurnEffect).Assembly;

            // Extract the short name. 
            string assemblyShortName = a.ToString().Split(',')[0];

            string uriString = "pack://application:,,,/" +
                assemblyShortName +
                ";component/" +
                relativeFile;

            return new Uri(uriString);
        }
        static ColorDodgeEffect()
        {
            _pixelShader.UriSource = MakePackUri("ColorDodgeEffect.ps");
        }

        public ColorDodgeEffect()
        {
            this.PixelShader = _pixelShader;
        }

        private static PixelShader _pixelShader = new PixelShader();
    }

//BlendModeEffect
  public class BlendModeEffect : ShaderEffect
    {
        public BlendModeEffect()
        {
            UpdateShaderValue(InputProperty);
            UpdateShaderValue(TextureProperty);
        }

        public Brush Input
        {
            get { return (Brush)GetValue(InputProperty); }
            set { SetValue(InputProperty, value); }
        }
        public static readonly DependencyProperty InputProperty =
            ShaderEffect.RegisterPixelShaderSamplerProperty
            (
                "Input",
                typeof(BlendModeEffect),
                0
            );

        public Brush Texture
        {
            get { return (Brush)GetValue(TextureProperty); }
            set { SetValue(TextureProperty, value); }
        }
        public static readonly DependencyProperty TextureProperty =
            ShaderEffect.RegisterPixelShaderSamplerProperty
            (
                "Texture",
                typeof(BlendModeEffect),
                1
            );
    }
Was it helpful?

Solution

As per the SO chat uses suggestion. I have called BrightContrastEffect as new Effect to the image in the slider changed event Handler. I set the biding values pro-grammatically.

private void cVal_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
   cColorEffects.SelectedIndex = 0;
   BrightContrastEffect bce = new BrightContrastEffect();
   BindingOperations.SetBinding(bce, BrightContrastEffect.ContrastProperty, new        Binding("Value") { Source = cVal });
ViewedPhoto.Effect = bce;
}

I have applied the same approached for the other sliders.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top