原文:深入WPF中的图像画刷(ImageBrush)之2——ImageBrush的铺设方式

--------------------------------------------------------------------------------
引用或转载时请保留以下信息:
大可山 [MSN:a3news(AT)hotmail.com]
http://www.zpxp.com http://www.brawdraw.com
萝卜鼠在线图形图像处理
--------------------------------------------------------------------------------

承接上篇:深入WPF中的图像画刷(ImageBrush)之1——ImageBrush使用举例,本篇着重介绍ImageBrush的铺设方式。

先来看看ImageBrush在不使用铺设方式时的效果:

图1为原图,图2,3,4为使用ImageBrush填充到椭圆中的效果。
图1的XAML代码:
  <Border Width="142" BorderBrush="#FF000000" BorderThickness="1,1,1,1" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Left" Margin="8,11.159,0,0" VerticalAlignment="Top" Height="150">
   <Image Source="xian.png" Stretch="Fill" Width="142" Height="150"/>
  </Border>
(Border作为定位及画边框用途)

图2的XAML代码:
<Ellipse x:Name="ellipseWithImageBrush" Stroke="#FF000000" Height="150" Margin="169.557,8,0,0" HorizontalAlignment="Left" Width="150" d:LayoutOverrides="Height" VerticalAlignment="Top">
   <Ellipse.Fill>
    <ImageBrush ImageSource="xian.png"/>
   </Ellipse.Fill>
  </Ellipse>
这里使用了Ellipse的Fill属性,这样ImageBrush就作为Ellipse的填充画刷了。

图3的XAML代码:
<Ellipse x:Name="ellipsFillWithImageBrush" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" Margin="0,11.159,167.443,0" VerticalAlignment="Top" Height="150" HorizontalAlignment="Right" Width="150">
  <Ellipse.Fill>
 <ImageBrush ImageSource="xian.png" Viewport="-0.05,-0.1,1,1.1" />
  </Ellipse.Fill>
</Ellipse>

图4的XAML代码:
<Ellipse x:Name="ellipsFillWithImageBrushFill" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" Margin="0,8,2,0" VerticalAlignment="Top" Height="150" HorizontalAlignment="Right" Width="150">
  <Ellipse.Fill>
    <ImageBrush ImageSource="xian.png" Viewport="-0.16,-0.16,1.18,1.28"/>
  </Ellipse.Fill>
</Ellipse>
你可以自行比较Viewport参数对最终效果产生的影响。(关于Viewport的更多说明见后)

再来看看ImageBrush的各种铺设方式效果:


下面分别予以介绍各种不同的辅设方式及其代码。

上图5至图9中,我们在ImageBrush中都使用了Viewport="0,0,0.3,0.3"。其中,前两个参数(0,0)表示起始位置,后面两个参数(0.3,0.3)表示缩放比例。例如图5(XAML代码):
<Ellipse x:Name="ellipsFillWithImageBrushTile" Stroke="#FF000000" HorizontalAlignment="Left" Margin="8,177.015,0,240.985" Width="208" Height="208">
   <Ellipse.Fill>
    <ImageBrush ImageSource="xian.png"
     Viewport="0,0,0.3,0.3"
     TileMode="None"
     AlignmentX="Left"
     AlignmentY="Top"
    />
   </Ellipse.Fill>
  </Ellipse>
(由于使用了TileMode.None,所以,圆形中小图没有平铺,只在左上角放了一张小图片)

图6的XAML代码:
<Ellipse x:Name="ellipsFillWithImageBrushTile_Copy3" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" Height="208" d:LayoutOverrides="Height" Margin="225,177.015,219,240.985">
   <Ellipse.Fill>
    <ImageBrush ImageSource="xian.png"
     TileMode="FlipX"
     AlignmentX="Left"
     AlignmentY="Top"
     Viewport="0,0,0.3,0.3"

    />
   </Ellipse.Fill>
  </Ellipse>
说明:由于这里使用了TileMode.FlipX,我们发现图片在水平(X)方向上做了镜像对称反转。

图7的XAML代码:
  <Ellipse x:Name="ellipsFillWithImageBrushTile_Copy1" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" Margin="0,177.015,4,240.985" d:LayoutOverrides="Width" HorizontalAlignment="Right" Width="208" Height="208">
   <Ellipse.Fill>
    <ImageBrush ImageSource="xian.png"
     Viewport="0,0,0.3,0.3"
     TileMode="FlipY"
     AlignmentX="Left"
     AlignmentY="Top
"
    />
   </Ellipse.Fill>
  </Ellipse>
说明:由于这里使用了TileMode.FlipY,我们发现图片在垂直(Y)方向上做了镜像对称反转(正立/倒立)。

图8的XAML代码:
  <Ellipse x:Name="ellipsFillWithImageBrushTile_Copy4" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" Width="208" Height="208" d:LayoutOverrides="Width, Height" HorizontalAlignment="Left" Margin="8,0,0,8" VerticalAlignment="Bottom">
   <Ellipse.Fill>
    <ImageBrush ImageSource="xian.png"
     Viewport="0,0,0.3,0.3"
     TileMode="Tile"
     AlignmentX="Left"
     AlignmentY="Top"
    />
   </Ellipse.Fill>
  </Ellipse>
说明:由于这里使用了TileMode.Tile,我们发现图片象铺地砖式地一张张平铺到一起,填充到圆中,但没有做任何镜像对称反转。

图9的XAML代码:
  <Ellipse x:Name="ellipsFillWithImageBrushTile_Copy2" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" Margin="225,0,219,8" d:LayoutOverrides="Height" VerticalAlignment="Bottom" Height="208">
   <Ellipse.Fill>
    <ImageBrush ImageSource="xian.png"
     Viewport="0,0,0.3,0.3"
     TileMode="FlipXY"
     AlignmentX="Left"
     AlignmentY="Top"
    />
   </Ellipse.Fill>
  </Ellipse>
说明:由于这里使用了TileMode.FlipXY,我们发现图片不但在水平方向上做了镜像对称反转,而且在垂直(Y)方向上做了镜像对称反转(正立/倒立)。

图10的XAML代码:
  <Ellipse x:Name="ellipsFillWithImageBrushTile_Copy" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" Height="208" d:LayoutOverrides="Height" HorizontalAlignment="Right" Margin="0,0,4,8" VerticalAlignment="Bottom" Width="208">
   <Ellipse.Fill>
    <ImageBrush ImageSource="xian.png"
     Viewport="0,0,0.18,0.18"
     TileMode="FlipXY"
     AlignmentX="Left"
     AlignmentY="Top"

    />
   </Ellipse.Fill>
  </Ellipse>
比较图9和图10,看看它们的代码,Viewport属性值由"0,0,0.3,0.3"变成了"0,0,0.18,0.18",这样,我们看到的里面填充的小图片比例缩得更小了(当然也就可以放更多的小图片了)。

需要指出的是,Viewport是在WPF中,使用一个Rect对象来表示。如果需要指定绝对数值而不是缩放比例,那么,就需要设置BrushMappingMode为BrushMappingMode.Absolute。同时指定Viewport的绝对值,比如将图6所对应的XAML代码改为:
<ImageBrush
      Viewport="0,0,25,25"
      ViewportUnits="Absolute"
      TileMode="Tile"
      ImageSource="xian.png" />

之后,得到如下效果:

这里的填充小图每个图的宽度和高度分别为25,25像素了。

为了加深大家的印象,不妨与GDI+的图片画刷作一个比较。
在GDI+中,与WPF中ImageBrush对应的是TextureBrush,与ImageBrush.TileMode对应的是TextureBrush.WrapMode, 而WrapMode的枚举值(注意是“枚举值”)是:Clamp,Tile,

TileFlipX,TileFlipY和TileFlipXY,分别与TileMode属性值(注意是“属性值”)的None,Tile,FlipX,FlipY和FlipXY对应。
与WPF中指定Viewport属性来控制起点及图像缩放不同的是:在GDI+中,graphic.RenderingOrigin将对TextureBrush的图片绘制的起始位置产生影响,如果需要对TextureBrush 对象的局部做几何变换缩放,可以使用ScaleTransform()方法,例如:
public void ScaleTransform_Example(PaintEventArgs e)
{
  TextureBrush tBrush = new TextureBrush(new Bitmap("texture.jpg"));
  tBrush.ScaleTransform(2, 1, MatrixOrder.Prepend);
  e.Graphics.FillRectangle(tBrush, 0, 0, 100, 100);
}

相关文章:
深入WPF中的图像画刷(ImageBrush)之1——ImageBrush使用举例
深入WPF中的图像画刷(ImageBrush)之2——ImageBrush的铺设方式〔本篇〕
简述WPF中的画刷(Brush)

深入WPF中的图像画刷(ImageBrush)之2——ImageBrush的铺设方式的更多相关文章

  1. 深入WPF中的图像画刷(ImageBrush)之1——ImageBrush使用举例

    原文:深入WPF中的图像画刷(ImageBrush)之1--ImageBrush使用举例 昨天我在<简述WPF中的画刷(Brush)  >中简要介绍了WPF中的画刷的使用.现在接着深入研究 ...

  2. 简述WPF中的图像像素格式(PixelFormats)

    原文:简述WPF中的图像像素格式(PixelFormats) --------------------------------------------------------------------- ...

  3. (C#)WPF:LinearGradientBrush 线性渐变画刷和RadialGradientBrush 圆形渐变画刷

    <Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/200 ...

  4. 简述WPF中的画刷(Brush)

    原文:简述WPF中的画刷(Brush) -------------------------------------------------------------------------------- ...

  5. WPF 10天修炼 第八天 - 形状、画刷和变换

    图形 在WPF中使用绘图最简单的就是使用Shape类.Shape类继承自FrameworkElement,是一个专门用来绘图的类.Shape类中年派生的类有直线.矩形.多边形和圆形等. System. ...

  6. 【WPF学习】第四十章 画刷

    画刷填充区域,不管是元素的背景色.前景色以及边框,还是形状的内部填充和笔画(Stroke).最简单的画刷类型是SolidColorBrush,这种画刷填充一种固定.连续的颜色.在XAML中设置形状的S ...

  7. WPF设计の画刷(Brush)

    一.什么是画刷 画刷是是一种渲染方式,用于填充图形形状,如矩形.椭圆.扇形.多边形和封闭路径.在GDI+中,画刷分为以下几种:SolidBrush,TextureBrush,HatchBrush,Li ...

  8. Sliverlight之 画刷

    1,5种画刷 (见Project15) (1)TextBlock控件中的Forground和BackGround属性是一个什么对象?它在前台的完整的写法是什么?(实际是.net做了一个转换,可以直接写 ...

  9. WPF中Brush类型

    画刷Brush使用 画刷类 SolidColorBrush LinearGradientBrush RadialGradientBrush ImageBrush VisualBrush Drawing ...

随机推荐

  1. IWorkSpace与IWorkSpaceFactory与IWorkSpaceEdit

    樱木 原文 IWorkSpace与IWorkSpaceFactory与IWorkSpaceEdit 1.IWorkSpace是一个容器,里面存放着各种空间数据和非空间数据,比如Featureclass ...

  2. [Ramda] allPass, propEq

    const needs = ['wifi', 'shower', 'laundry']; const homes = [{ name: 'Home 1', wifi: 'y', shower: 'y' ...

  3. 为什么位运算可以实现加法(1、 不考虑进位的情况下位运算符中的异或^可以表示+号)(2、 位运算符中的与运算符&和左移运算符<<可以模拟加法中的进位)(3、位运算不仅可以做加法,还可以做其它的乘法减法等:计算机本质是二进制运算)

    为什么位运算可以实现加法(1. 不考虑进位的情况下位运算符中的异或^可以表示+号)(2. 位运算符中的与运算符&和左移运算符<<可以模拟加法中的进位)(3.位运算不仅可以做加法,还 ...

  4. ccpc2016长春站打铁记(后记)

    Day3 "学术交流日" 自己进我的空间看吧. http://user.qzone.qq.com/190741511/4

  5. centos7安装jdk+tomcat+nginx+mysql

    公司新项目要在linux下部署,搭建一下java运行环境,记录一下. 一.安装mysql 1去官网下载mysql,下载后并解压,我把mysql安装在/usr/local/mysql路径下 -linux ...

  6. [RxJS] Split an RxJS Observable into groups with groupBy

    groupBy() is another RxJS operator to create higher order observables. In this lesson we will learn ...

  7. Android中HandlerThread的使用及源代码解析

    关于Hanlder的基本使用能够參见博文<Android中Handler的使用>,假设想了解Handler.Looper.Thread等的相互关系以及内部实现原理能够參见博文<深入源 ...

  8. Android组件——使用DrawerLayout仿网易新闻v4.4侧滑菜单

    摘要: 转载请注明出处:http://blog.csdn.net/allen315410/article/details/42914501 概述        今天这篇博客将记录一些关于DrawerL ...

  9. 数据序列化之protobuf

    数据序列化之protobuf 很多时候需要将一些数据打包,就是把这些数据搞在一起,方便处理.最常见的情况就是把需要传输的数据,当然数据不止一条,打包成一个消息,然后发送出去,接收端再以一定的规则接收并 ...

  10. 2015年工作中遇到的问题:81-90,标题党-Nginx与真实IP-Mybatis等

     81."标题党"与"百度收录"问题. 很久以来,就发现那些"标题党"的收录和排名情况非常好,比如CSDN某篇文章,就随便一写,就排在了第一 ...