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