【WPF】Brush画刷

概览

 

其他画刷直接看wpf编程宝典,以下是书上将的不透彻的做一下笔记

TileBrush(ImageBrush,DrawingBrush和VisualBrush

我们知道TileBrush是WPF中一个战斗力爆表的虚基类,从它派生出的DrawingBrush,ImageBrush和VisualBrush在WPF图形编程中发挥着重要作用。然而关于TileBrush的Viewbox、Viewport两大重要属性经常令人感到迷惑,Stretch、AlignmentX/Y两种对齐方式也往往让人搞混。这些知识在MSDN上讲得过于模棱两可,网上似乎也没有能够很清晰并且有条理地讲述它们之间关系的文章。于是今天下午我又牺牲了一下午的大好时光,做了一些实验来研究这个问题。

Silverlight把TileBrush的Viewbox和Viewport去掉了,于是战斗力暴减。

在讲述之前,我假设读这篇文章的你已经知道了这四个玩意的基本用法,若需要入门的话请参阅参考资料[1]和MSDN上的相关内容。本文主要分析TileBrush是如何利用Viewbox,Viewport以及Stretch,AlignmentX/Y来进行绘制的。

左下角表示的是我们的Brush用来绘制的原始素材(以下简称为原图,虽然它不一定来自图片文件)。左上角发亮的部分就是Viewbox区域。右边四个方框就是Viewport区域。可能有人认为右边发灰的部分是不显示的,其实不然,右边的发光部分只是为了突出Viewbox相对于Viewport的位置(默认设置AlignmentX/Y都为Center)。

Viewbox指示了一块基于原图的显示区域。请注意TileBrush并不会在原图中裁减掉Viewbox之外的内容,Viewbox只是起到提示作用,只有和另外三种属性结合到一起才能决定最终的显示效果。

ViewboxUnits: 基于原图的显示区域,定位方式,是采用百分比还是像素

Viewport指示了一块基于画布的显示区域。这里的画布就是包含了这个TileBrush的区域,如果画布开启了ClipToBounds(也在Silverlight中被砍掉了),则不管Viewport如何,超出画布区域之外的像素就都被和谐掉了,不会被绘制。

ViewportUnits:基于画布的显示区域,定位方式,是采用百分比还是像素

当指定了Viewbox和Viewport之后,就是Stretch、AlignmentX/Y登场了,它俩决定了Viewbox相对于Viewport的拉伸方式和相对位置。

先看Stretch,它决定了Viewbox相对于Viewport的拉伸方式。Stretch有四种取值:

1、None。取None时,就和什么都没发生一样,没有任何的伸缩调整。此时若Viewbox和Viewport的大小不同,则会根据AlignmentX/Y的取值来调整Viewbox相对于Viewport的位置。参见上图右边左上角的小图。

2、Fill。取Fill时,AlignmentX/Y失去作用,然后将Viewbox拉伸以填满Viewport,原图中Viewbox区域以外的部分将不可见。参见上图右边右上角的小图。

3、Uniform。取Uniform时,将把Viewbox拉伸,直到Viewbox的一个边抵达Viewport的边界为止。此时若Viewbox和Viewport的纵横比不同,则会根据AlignmentX/Y的取值来调整Viewbox相对于Viewport的位置。参见上图右边左下角的小图。

4、UniformToFill。取Uniform时,将把Viewbox拉伸,直到Viewbox的另一个边抵达Viewport的边界为止。此时若Viewbox和Viewport的纵横比不同,则会根据AlignmentX/Y的取值来调整Viewbox相对于Viewport的位置。原图中Viewbox区域以外的部分将不可见。参见上图右边右下角的小图。

再来看AlignmentX/Y。仅当

1、Stretch为Uniform或UniformToFill,并且Viewbox和Viewport具有不同的纵横比

2、Stretch为None并且Viewbox和Viewport具有不同的大小

这两种情况时,才会应用AlignmentX/Y来调整Viewbox相对于Viewport的位置。需要注意的是Viewbox相当于原图的一个把手,AlignmentX/Y移动Viewbox的同时也会移动原图。

ImageBrush画刷

ImageBrush 是一种将自身内容定义为图像的 TileBrush,图像通过它的 ImageSource 属性指定。 您可以控制图像的拉伸、对齐和平铺方式,因此可以生成图案和其他效果下面的图像演示使用 ImageBrush 可以实现的一些效果。

各种属性设置如下:

 

 代码如下:

<Window Style="{DynamicResource WindowStyle1}" x:Class="WpfApp4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp4"
        Width="800" Height="600"
        
        mc:Ignorable="d"
        Title="MainWindow"
      
        Background="Transparent"
        WindowStartupLocation="CenterScreen"
        AllowsTransparency="True"
        WindowStyle="None"
        ResizeMode="CanResizeWithGrip"  
         
        >
    <Window.Resources>

        <GeometryGroup x:Key="geo">
            <RectangleGeometry Rect="0,0,100,100"></RectangleGeometry>
            <EllipseGeometry Center="150,150" RadiusX="35" RadiusY="25"></EllipseGeometry>
        </GeometryGroup>



    </Window.Resources>
    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="109*"/>
            <ColumnDefinition Width="291*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="3*"/>
            <RowDefinition Height="7*"/>
        </Grid.RowDefinitions>
        <Canvas Grid.Column="1" Grid.Row="1"  >
            <!-- Viewport 图1对比图2-->
            <!--使用Viewbox完整的图片 ,Viewport 使用一半的画布Vs使用完全画布  不够的按设定Stretch属性拉伸-->
            <Rectangle Height="100" Width="149" RadiusX="10" RadiusY="10" Stroke="AliceBlue">
                <!--图1 横向-->
                <Rectangle.Fill>
                    <ImageBrush ImageSource="/QQ截图20220813082913.png" Viewbox="0,0 1,1"  Viewport="0,0 0.5,0.5" ></ImageBrush>
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Height="100" Width="185" RadiusX="10" RadiusY="10" Stroke="AliceBlue" Canvas.Left="154">
                <Rectangle.Fill>
                    <!--图2 横向-->
                    <ImageBrush ImageSource="/QQ截图20220813082913.png" Viewbox="0,0 1,1"   ></ImageBrush>
                </Rectangle.Fill>
            </Rectangle>

<!--Viewbox 图1图2对比图3 --> <!--Viewbox 对比 使用一半图片Vs使用完整画布 不够的按设定Stretch属性拉伸--> <Rectangle Height="100" Width="200" RadiusX="10" RadiusY="10" Stroke="AliceBlue" Canvas.Left="341.37"> <Rectangle.Fill> <!--图3 横向--> <ImageBrush ImageSource="/QQ截图20220813082913.png" Viewbox="0,0 0.5,0.5" ></ImageBrush> </Rectangle.Fill> </Rectangle>

<!--Viewbox 图1 对比图4 --> <!--Viewbox 对比 整个画布填充方式 不够的按设定Stretch属性拉伸--> <Rectangle Height="100" Width="185" RadiusX="10" RadiusY="10" Stroke="AliceBlue" Canvas.Top="119"> <!--图4 横向--> <Rectangle.Fill> <ImageBrush ImageSource="/QQ截图20220813082913.png" Viewbox="0,0 0.5,1" Viewport="0,0 0.2,1" TileMode="FlipXY" ></ImageBrush> </Rectangle.Fill> </Rectangle>

<!--Viewbox 图4 对比图5 --> <!--Stretch="None" 不拉伸图片,不沟用不填充,保证图片不变形 --> <Rectangle Height="100" Width="151" RadiusX="10" RadiusY="10" Stroke="AliceBlue" Canvas.Top="119" Canvas.Left="185"> <Rectangle.Fill> <!--图5 横向--> <ImageBrush ImageSource="/QQ截图20220813082913.png" Viewbox="0,0 0.5,1" Viewport="0,0 0.2,1" Stretch="None" AlignmentX="Right" TileMode="FlipXY" ></ImageBrush> </Rectangle.Fill> </Rectangle>

<!--Viewbox 图4图5 对比图6 --> <Rectangle Height="100" Width="146" RadiusX="10" RadiusY="10" Stroke="AliceBlue" Canvas.Top="119" Canvas.Left="341.37"> <Rectangle.Fill> <!--图6 横向--> <ImageBrush ImageSource="/QQ截图20220813082913.png" Viewbox="0,0 0.5,1" Viewport="0,0 0.2,1" Stretch="None" AlignmentX="Left" TileMode="FlipXY" ></ImageBrush> </Rectangle.Fill> </Rectangle> <Rectangle Height="100" Width="146" RadiusX="10" RadiusY="10" Stroke="AliceBlue" Canvas.Top="259" Canvas.Left="19.5"> <Rectangle.Fill> <!--图7 横向--> <ImageBrush ImageSource="/QQ截图20220813082913.png" Viewbox="0,0 0.5,1" Viewport="0,0 0.2,1" Stretch="None" AlignmentX="Center" TileMode="FlipXY" ></ImageBrush> </Rectangle.Fill> </Rectangle> </Canvas> </Grid> </Window>

 VisualBrush(镜像笔刷)

作用:做放大镜、做倒影、做窗口缩略图

VisualBrush是一种比较特殊的笔刷,它的功能仍然是用来给元素填充图案,但它的内容却可以是各种控件。

你可以将其理解为一个普通的容器,但在其内部的所有控件都会失去交互能力,而只保留显示能力。

倒影

 

 

下面看代码:

 

 

<Grid>
        <TextBox Height="40" Margin="42,51,40,0" Name="textBox1" VerticalAlignment="Top" FontSize="24" />
        <Rectangle Margin="42,102,42,0" Name="rectangle1" Stroke="Black" Height="40" VerticalAlignment="Top" StrokeThickness="0">
            <Rectangle.Fill>
                <VisualBrush Visual="{Binding ElementName=textBox1}">
                    <VisualBrush.RelativeTransform>
                        <TransformGroup>
                            <ScaleTransform ScaleX="1" ScaleY="-1" />
                            <TranslateTransform Y="1" />
                        </TransformGroup>
                    </VisualBrush.RelativeTransform>
                </VisualBrush>
            </Rectangle.Fill>
        </Rectangle>
    </Grid>

 

这里的ScaleX是:

获取或设置 x 方向的缩放比例。这是一个依赖项属性。

返回值:
x 方向的缩放比例。默认值为 1。

ScaleY是:

获取或设置 y 方向的缩放比例。这是一个依赖项属性。

返回值:
y 方向的缩放比例。默认值为 1。

 

posted @ 2022-08-13 10:01  小林野夫  阅读(605)  评论(0编辑  收藏  举报
原文链接:https://www.cnblogs.com/cdaniu/