什么是马赛克(Mask)
相信许多看电影的朋友都知道什么是马赛克,通俗的将就是视频或者图片上方有一层模糊的区域,以使这块区域不可见。
下面的文字摘自百度百科:
马赛克(Mosaic),建筑专业名词为锦砖,分为陶瓷锦砖和玻璃锦砖两种。是一种装饰艺术,通常使用许多小石块或有色玻璃碎片拼成图案,在教堂中的玻璃艺品,又称为花窗玻璃(stained glass)。在拜占庭帝国时代,马赛克随着基督教兴起而发展为教堂及宫殿中的壁画形式。现今马赛克泛指这种类型五彩斑斓的视觉效果。马赛克也指现行广为使用的一种图像(视频)处理手段,此手段将影像特定区域的色阶细节劣化并造成色块打乱的效果,因为这种模糊看上去有一个个的小格子组成,便形象的称这种画面为马赛克。其目的通常是使之无法辨认。
先来看一下程序的运行结果:
要实现这个效果,我们是通过图片的Clip属性。
图片的Cilp属性
用于确定剪辑区域大小的几何图形。一个典型的例子如下:
在没有使用Clip属性之前图片是这样的:
使用的代码是MSDN上的代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<
Image
Source ="sampleImages\Waterlilies.jpg"
Width ="200" Height ="150" HorizontalAlignment ="Left" >
< Image.Clip >
< EllipseGeometry
RadiusX ="100"
RadiusY ="75"
Center ="100,75" />
</ Image.Clip >
</ Image >
Source ="sampleImages\Waterlilies.jpg"
Width ="200" Height ="150" HorizontalAlignment ="Left" >
< Image.Clip >
< EllipseGeometry
RadiusX ="100"
RadiusY ="75"
Center ="100,75" />
</ Image.Clip >
</ Image >
CompositionTarget.Rendering
CompositionTarget 是一个类,表示正在其上绘制您的应用程序的显示图面。 WPF 动画引擎为创建基于帧的动画提供了许多功能。 但是,在有些应用程序方案中,您需要根据每个帧控制呈现。 使用 CompositionTarget 对象,可以基于每个帧回调来创建自定义动画。
我们在程序中使用这个重绘的方法来重绘屏幕,具体的代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
void
CompositionTarget_Rendering(
object
sender, EventArgs e)
{
double springness = Spring;
double scale = 1 ;
// 遍历每一个图片
for ( int i = 0 ; i < images.Length; i ++ )
{
// 当前的图片
Image image = images[i];
// 根据目标点重定位图片
double offsetX = - (image.Width - ImageWidth) / ImageWidth * targetPoint.X;
double offsetY = - (image.Height - ImageHeight) / ImageHeight * targetPoint.Y;
image.SetValue(Canvas.LeftProperty, offsetX);
image.SetValue(Canvas.TopProperty, offsetY);
// 更新马赛克
EllipseGeometry ellipseGeometry = (EllipseGeometry)image.Clip;
Point center = ellipseGeometry.Center;
center.X = center.X + (targetPoint.X - offsetX - center.X) * springness;
center.Y = center.Y + (targetPoint.Y - offsetY - center.Y) * springness;
ellipseGeometry.Center = center;
image.Clip = ellipseGeometry;
springness *= SpringDrag;
scale += LayerScale;
}
}
{
double springness = Spring;
double scale = 1 ;
// 遍历每一个图片
for ( int i = 0 ; i < images.Length; i ++ )
{
// 当前的图片
Image image = images[i];
// 根据目标点重定位图片
double offsetX = - (image.Width - ImageWidth) / ImageWidth * targetPoint.X;
double offsetY = - (image.Height - ImageHeight) / ImageHeight * targetPoint.Y;
image.SetValue(Canvas.LeftProperty, offsetX);
image.SetValue(Canvas.TopProperty, offsetY);
// 更新马赛克
EllipseGeometry ellipseGeometry = (EllipseGeometry)image.Clip;
Point center = ellipseGeometry.Center;
center.X = center.X + (targetPoint.X - offsetX - center.X) * springness;
center.Y = center.Y + (targetPoint.Y - offsetY - center.Y) * springness;
ellipseGeometry.Center = center;
image.Clip = ellipseGeometry;
springness *= SpringDrag;
scale += LayerScale;
}
}
打造马赛克
我们使用多重图片堆叠来打造马赛克,具体的代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
///
<summary>
/// 将打过马赛克的图片添加到窗体中
/// </summary>
private void addImage()
{
double radius = InitialRadius; // 初始半径
double scale = 1 ;
ImageSource imageSource = new BitmapImage( new Uri(ImagePath, UriKind.Relative));
// 遍历层数
for ( int i = 0 ; i < LayerCount; i ++ )
{
// 创建马赛克
EllipseGeometry ellipseGeometry = new EllipseGeometry();
ellipseGeometry.Center = new Point( 0 , 0 );
ellipseGeometry.RadiusX = radius;
ellipseGeometry.RadiusY = radius;
double offsetX = ImageWidth * ( 1 - scale) / 2 ;
double offestY = ImageHeight * ( 1 - scale) / 2 ;
// 创建图片,并设置图片的位置
Image image = new Image();
image.Source = imageSource;
image.Width = ImageWidth * scale;
image.Height = ImageHeight * scale;
image.SetValue(Canvas.LeftProperty, offsetX);
image.SetValue(Canvas.TopProperty, offestY);
// 用于确定剪辑区域大小的几何图形
image.Clip = ellipseGeometry;
// 将马赛克和图片添加到屏幕中
images[i] = image;
LayoutRoot.Children.Insert( 0 , image);
scale += LayerScale;
radius += RadiusIncrement;
}
// 将图片添加到窗体的背景中
Image background = new Image();
background.Source = imageSource;
LayoutRoot.Children.Insert( 0 , background);
}
/// 将打过马赛克的图片添加到窗体中
/// </summary>
private void addImage()
{
double radius = InitialRadius; // 初始半径
double scale = 1 ;
ImageSource imageSource = new BitmapImage( new Uri(ImagePath, UriKind.Relative));
// 遍历层数
for ( int i = 0 ; i < LayerCount; i ++ )
{
// 创建马赛克
EllipseGeometry ellipseGeometry = new EllipseGeometry();
ellipseGeometry.Center = new Point( 0 , 0 );
ellipseGeometry.RadiusX = radius;
ellipseGeometry.RadiusY = radius;
double offsetX = ImageWidth * ( 1 - scale) / 2 ;
double offestY = ImageHeight * ( 1 - scale) / 2 ;
// 创建图片,并设置图片的位置
Image image = new Image();
image.Source = imageSource;
image.Width = ImageWidth * scale;
image.Height = ImageHeight * scale;
image.SetValue(Canvas.LeftProperty, offsetX);
image.SetValue(Canvas.TopProperty, offestY);
// 用于确定剪辑区域大小的几何图形
image.Clip = ellipseGeometry;
// 将马赛克和图片添加到屏幕中
images[i] = image;
LayoutRoot.Children.Insert( 0 , image);
scale += LayerScale;
radius += RadiusIncrement;
}
// 将图片添加到窗体的背景中
Image background = new Image();
background.Source = imageSource;
LayoutRoot.Children.Insert( 0 , background);
}
详细的代码可以参加源代码。
英文链接:http://www.shinedraw.com/animation-effect/flash-vs-silverlight-water-effect/