深入WPF中的映像畫刷(ImageBrush)之2——ImageBrush的鋪設方式 引用:http://blog.csdn.net/johnsuna/article/details/1772969
蘿蔔鼠線上圖形影像處理
--------------------------------------------------------------------------------
承接上篇:深入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);
}