什么是马赛克(Mask)

相信许多看电影的朋友都知道什么是马赛克,通俗的将就是视频或者图片上方有一层模糊的区域,以使这块区域不可见。

下面的文字摘自百度百科:

马赛克(Mosaic),建筑专业名词为锦砖,分为陶瓷锦砖和玻璃锦砖两种。是一种装饰艺术,通常使用许多小石块或有色玻璃碎片拼成图案,在教堂中的玻璃艺品,又称为花窗玻璃(stained glass)。在拜占庭帝国时代,马赛克随着基督教兴起而发展为教堂及宫殿中的壁画形式。现今马赛克泛指这种类型五彩斑斓的视觉效果。马赛克也指现行广为使用的一种图像(视频)处理手段,此手段将影像特定区域的色阶细节劣化并造成色块打乱的效果,因为这种模糊看上去有一个个的小格子组成,便形象的称这种画面为马赛克。其目的通常是使之无法辨认。

先来看一下程序的运行结果:

要实现这个效果,我们是通过图片的Clip属性。

图片的Cilp属性

用于确定剪辑区域大小的几何图形。一个典型的例子如下:

在没有使用Clip属性之前图片是这样的:

 

使用的代码是MSDN上的代码

 
  
  1. <Image   
  2.   Source="sampleImages\Waterlilies.jpg"   
  3.   Width="200" Height="150" HorizontalAlignment="Left"> 
  4.   <Image.Clip> 
  5.     <EllipseGeometry 
  6.       RadiusX="100" 
  7.       RadiusY="75" 
  8.       Center="100,75"/> 
  9.   </Image.Clip> 
  10. </Image> 

使用了Clip属性之后:

CompositionTarget.Rendering
CompositionTarget 是一个类,表示正在其上绘制您的应用程序的显示图面。 WPF 动画引擎为创建基于帧的动画提供了许多功能。 但是,在有些应用程序方案中,您需要根据每个帧控制呈现。 使用 CompositionTarget 对象,可以基于每个帧回调来创建自定义动画。

我们在程序中使用这个重绘的方法来重绘屏幕,具体的代码如下:

 
  
  1. void CompositionTarget_Rendering(object sender, EventArgs e)  
  2.         {  
  3.             double springness = Spring;  
  4.             double scale = 1;  
  5.  
  6.             //遍历每一个图片  
  7.             for (int i = 0; i < images.Length; i++)  
  8.             {  
  9.                 //当前的图片  
  10.                 Image image = images[i];  
  11.  
  12.                 // 根据目标点重定位图片  
  13.                 double offsetX = -(image.Width - ImageWidth) / ImageWidth * targetPoint.X;  
  14.                 double offsetY = -(image.Height - ImageHeight) / ImageHeight * targetPoint.Y;  
  15.                 image.SetValue(Canvas.LeftProperty, offsetX);  
  16.                 image.SetValue(Canvas.TopProperty, offsetY);  
  17.  
  18.                 // 更新马赛克  
  19.                 EllipseGeometry ellipseGeometry = (EllipseGeometry)image.Clip;  
  20.                 Point center = ellipseGeometry.Center;  
  21.                 centercenter.X = center.X + (targetPoint.X - offsetX - center.X) * springness;  
  22.                 centercenter.Y = center.Y + (targetPoint.Y - offsetY - center.Y) * springness;  
  23.                 ellipseGeometry.Center = center;  
  24.                 image.Clip = ellipseGeometry;  
  25.  
  26.                 springness *= SpringDrag;  
  27.                 scale += LayerScale;  
  28.             }  
  29.         } 

打造马赛克 
 

我们使用多重图片堆叠来打造马赛克,具体的代码如下:

 
  
  1. /// <summary> 
  2.         /// 将打过马赛克的图片添加到窗体中  
  3.         /// </summary> 
  4.         private void addImage()  
  5.         {  
  6.             double radius = InitialRadius;//初始半径  
  7.             double scale = 1;  
  8.  
  9.             ImageSource imageSource = new BitmapImage(new Uri(ImagePath, UriKind.Relative));  
  10.             //遍历层数  
  11.             for (int i = 0; i < LayerCount; i++)  
  12.             {  
  13.                 // 创建马赛克  
  14.                 EllipseGeometry ellipseGeometry = new EllipseGeometry();  
  15.                 ellipseGeometry.Center = new Point(0, 0);  
  16.                 ellipseGeometry.RadiusX = radius;  
  17.                 ellipseGeometry.RadiusY = radius;  
  18.  
  19.                 double offsetX = ImageWidth * (1 - scale) / 2;  
  20.                 double offestY = ImageHeight * (1 - scale) / 2;  
  21.  
  22.                 // 创建图片,并设置图片的位置  
  23.                 Image image = new Image();  
  24.                 image.Source = imageSource;  
  25.                 image.Width = ImageWidth * scale;  
  26.                 image.Height = ImageHeight * scale;  
  27.                 image.SetValue(Canvas.LeftProperty, offsetX);  
  28.                 image.SetValue(Canvas.TopProperty, offestY);  
  29.  
  30.                 // 用于确定剪辑区域大小的几何图形  
  31.                 image.Clip = ellipseGeometry;  
  32.  
  33.                 // 将马赛克和图片添加到屏幕中  
  34.                 images[i] = image;  
  35.                 LayoutRoot.Children.Insert(0, image);  
  36.  
  37.                 scale += LayerScale;  
  38.                 radius += RadiusIncrement;  
  39.             }  
  40.  
  41.             // 将图片添加到窗体的背景中  
  42.             Image background = new Image();  
  43.             background.Source = imageSource;  
  44.             LayoutRoot.Children.Insert(0, background);  
  45.         } 

详细的代码可以参加源代码。
WPF版源文件下载:

Silverlight版源文件下载:

英文链接:http://www.shinedraw.com/animation-effect/flash-vs-silverlight-water-effect/