How to blur background images in Android
The easiest way to do that is use a library. Take a look at this one: https://github.com/wasabeef/Blurry
With the library you only need to do this:
Blurry.with(context)
.radius(10)
.sampling(8)
.color(Color.argb(66, 255, 255, 0))
.async()
.onto(rootView);
How to set the blur level of a view background
Android doesn't provide this functionality for UI elements as iOS does. It's not part of the UI rendering engine and to obtain these kind of effects you need to use third-party libraries which will essentially take a snapshot of the drawing cache, reduce its size for a faster processing and then put the generated bitmap into a view.
Here are some example libraries:
- BlurrView
- Blurry
Please bear in mind that this will have a serious performance hit on mid-low end phones.
how to set Blur/dim background
Use this to set your opacity
android:alpha="0.5"
OR
yourView.getBackground().setAlpha(100);
How to blur the background behind a control
If want to blur the image behind the Button
(or a transparent control in general) you have to follow a different approach.
You need the exact tile of the image in order to blur it using the BlurEffect
.
In order to not blur the Button
itself, you must add alayer beneath the button that has the BlurEffect
applied.
The following example extends a ContentControl
named BlurHost
that renders the Content
e.g., the Button
, on top of a Border
element that will actualy blur the background using a VisualBrush
.
The brush itself has a tile defined that is located at the position of the BlurHost
which hosts the Button
(or any other transparent control).
The basic steps to implement a blurred background:
- Add the background image
- Create a blur layer beneath the element
- Get the bounds of the element e.g., the Button which is located relative to the parent of the Image (preferably the root container)
- Use the bounding rectangle to define the tile of the VisualBrush (the actual section of the image)
- Apply the brush on the blur layer
Usage example
MainWindow.xaml
<Window>
<!-- Allow the root grid to stretch accross the Window -->
<Grid>
<Image x:Name="img" Source="/someImage.png" />
<!--
Optionally override the default BlurEffect
by setting the BlurHost.BlurEffect property
-->
<local:BlurHost BlurBackground="{Binding ElementName=img}"
BlurOpacity="1"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Button Background="Transparent"
FontSize="48"
Content="Acquista ora- $23.99" />
</local:BlurHost>
</Grid>
</Window>
Implementation example
The implementation is simple. You have to add property changed handlers in order to make the control dynamic.
BlurHost.cs
The ContentControl
serves as a container. The blurred background is visible at the transparent areas of the content.
public class BlurHost : ContentControl
{
public Visual BlurBackground
{
get => (Visual)GetValue(BlurBackgroundProperty);
set => SetValue(BlurBackgroundProperty, value);
}
public static readonly DependencyProperty BlurBackgroundProperty =
DependencyProperty.Register(
"BlurBackground",
typeof(Visual),
typeof(BlurHost),
new PropertyMetadata(default(Visual), OnBlurBackgroundChanged));
public double BlurOpacity
{
get => (double)GetValue(BlurOpacityProperty);
set => SetValue(BlurOpacityProperty, value);
}
public static readonly DependencyProperty BlurOpacityProperty =
DependencyProperty.Register(
"BlurOpacity",
typeof(double),
typeof(BlurHost),
new PropertyMetadata(1.0));
public BlurEffect BlurEffect
{
get => (BlurEffect)GetValue(BlurEffectProperty);
set => SetValue(BlurEffectProperty, value);
}
public static readonly DependencyProperty BlurEffectProperty =
DependencyProperty.Register(
"BlurEffect",
typeof(BlurEffect),
typeof(BlurHost),
new PropertyMetadata(
new BlurEffect()
{
Radius = 10,
KernelType = KernelType.Gaussian,
RenderingBias = RenderingBias.Performance
}));
private Border PART_BlurDecorator { get; set; }
private VisualBrush BlurDecoratorBrush { get; set; }
static BlurHost()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BlurHost), new FrameworkPropertyMetadata(typeof(BlurHost)));
}
public BlurHost()
{
Loaded += OnLoaded;
// TODO::Update Opacity of VisualBrush when property BlurOpacity changes
this.BlurDecoratorBrush = new VisualBrush()
{
ViewboxUnits = BrushMappingMode.Absolute,
Opacity = this.BlurOpacity
};
}
private void DrawBlurredElementBackground()
{
if (!TryFindVisualRootContainer(this, out FrameworkElement rootContainer))
{
return;
}
// Get the section of the image where the BlurHost element is located
Rect elementBounds = TransformToVisual(rootContainer)
.TransformBounds(new Rect(this.RenderSize));
// Use the section bounds to actually "cut out" the image tile
this.BlurDecoratorBrush.Viewbox = elementBounds;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (TryFindVisualRootContainer(this, out FrameworkElement rootContainer))
{
rootContainer.SizeChanged += OnRootContainerElementResized;
}
DrawBlurredElementBackground();
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.PART_BlurDecorator = GetTemplateChild("PART_BlurDecorator") as Border;
this.PART_BlurDecorator.Effect = this.BlurEffect;
this.PART_BlurDecorator.Background = this.BlurDecoratorBrush;
}
private static void OnBlurBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var this_ = d as BlurHost;
this_.BlurDecoratorBrush.Visual = e.NewValue as Visual;
this_.DrawBlurredElementBackground();
}
private void OnRootContainerElementResized(object sender, SizeChangedEventArgs e)
=> DrawBlurredElementBackground();
private bool TryFindVisualRootContainer(DependencyObject child, out FrameworkElement rootContainerElement)
{
rootContainerElement = null;
DependencyObject parent = VisualTreeHelper.GetParent(child);
if (parent == null)
{
return false;
}
if (parent is not Window visualRoot)
{
return TryFindVisualRootContainer(parent, out rootContainerElement);
}
rootContainerElement = visualRoot.Content as FrameworkElement;
return true;
}
}
Generic.xaml
The default Style
for the BlurHost
. The Generic.xaml file is located in the Themes folder of the application (project).
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Net.Wpf">
<Style TargetType="local:BlurHost">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:BlurHost">
<Grid>
<!-- Blur layer beneath the hosted element (ContentPresenter) -->
<Border x:Name="PART_BlurDecorator"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"/>
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Related Topics
Apache Httpclient Digest Authentication
How to Delete Files Programmatically on Android
Eclipse: Jvm Terminated. Exit Code=2
Issue: Passing Large Data to Second Activity
Multiple Dex Files Define <My Package>/Buildconfig, Can't Find the Cause:
What Is the Correct Way to Do Inserts/Updates/Deletes in Android SQLitedatabase Using a Query String
How to Get from Jruby a Correctly Typed Ruby Implementation of a Java Interface
Finding Signed Angle Between Vectors
Setting the Default Font of Swing Program
Unhandled Exception Type Error
Fragment Add or Replace Not Working
How to Adjust Microphone Sensitivity While Recording Audio in Android
How to Create JSON Object Using String
Android Color Notification Icon
Design Lib - Coordinatorlayout/Collapsingtoolbarlayout with Gridview/Listview
Pdfbox:Pdpagecontentstream's Append Mode Misbehaving
Simple Sso - Using Custom Authentication - Cas or Some Oauth or Openid Server