Рисование с помощью объектов Image, Drawing и Visual
В этом разделе описывается использование ImageBrush, DrawingBrush, и VisualBrush объекты Заливка области с изображением, Drawing, или Visual.
Предварительные требования
Для понимания этого раздела необходимо ознакомиться с различными типами кистей, имеющихся в Windows Presentation Foundation (WPF), и их основными возможностями. Общие сведения см. в разделе Общие сведения о кистях WPF.
Закрашивание области с помощью Image
ImageBrush Закрашивает область с ImageSource. Это наиболее распространенный тип ImageSource для использования с ImageBrush является BitmapImage, которая описывает растрового изображения. Можно использовать DrawingImage для заполнения с помощью Drawing , но проще использовать DrawingBrush вместо этого. Дополнительные сведения о ImageSource объектов, см. в разделе Обзор работы с образами.
Для заполнения с помощью ImageBrush, создание BitmapImage и используйте его для загрузки содержимого точечного рисунка. Затем с помощью BitmapImage присвоить ImageSource свойство ImageBrush. Наконец, примените ImageBrush на объект, который нужно нарисовать. В XAML, можно просто задать ImageSource свойство ImageBrush на путь к загружаемому изображению.
Как и все Brush объектов, ImageBrush может использоваться для рисования объектов, таких как фигуры, панели, элементы управления и текст. На следующем рисунке показан некоторые эффекты, которые могут быть обеспечены ImageBrush.
Объекты, заполненные при помощи ImageBrush
По умолчанию ImageBrush растягивает изображения до полного заполнения области закрашиваемой, возможно искажение изображения, если область рисования имеет другие пропорции изображения. Это поведение можно изменить, изменив Stretch свойство со значения по умолчанию Fill для None, Uniform, или UniformToFill. Так как ImageBrush — это разновидность TileBrush, можно указать точно в том случае, как кисть изображения заполняет область вывода и даже создать шаблоны. Дополнительные сведения о дополнительных TileBrush функции, см. в разделе Общие сведения о TileBrush.
Пример Заполнение объекта с растровым изображением
В следующем примере используется ImageBrush для закрашивания Background из Canvas.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Microsoft.Samples.BrushExamples.ImageBrushExample"
WindowTitle="ImageBrush Example"
Background="White">
<StackPanel>
<Canvas
Height="200" Width="300">
<Canvas.Background>
<ImageBrush ImageSource="sampleImages\Waterlilies.jpg" />
</Canvas.Background>
</Canvas>
</StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Microsoft.Samples.BrushExamples
{
public class ImageBrushExample : Page
{
public ImageBrushExample()
{
StackPanel mainPanel = new StackPanel();
canvasBackgroundExample(mainPanel);
this.Content = mainPanel;
}
private void canvasBackgroundExample(Panel mainPanel)
{
BitmapImage theImage = new BitmapImage
(new Uri("sampleImages\\Waterlilies.jpg", UriKind.Relative));
ImageBrush myImageBrush = new ImageBrush(theImage);
Canvas myCanvas = new Canvas();
myCanvas.Width = 300;
myCanvas.Height = 200;
myCanvas.Background = myImageBrush;
mainPanel.Children.Add(myCanvas);
}
}
}
Закрашивание области с помощью Drawing
Объект DrawingBrush позволяет закрасить область фигуры, текст, изображения и видео. Фигуры внутри закрашивающей кисти сами могут быть закрашены сплошным цветом, градиент, изображения, или даже другим DrawingBrush. На следующем рисунке показано несколько способов использования DrawingBrush.
Объекты, заполненные при помощи DrawingBrush
Объект DrawingBrush закрашивает область с Drawing объекта. Объект Drawing объект описывает отображаемое содержимое, например фигуру, растровое изображение, видео или строку текста. Различные типы рисунков описывают различные типы содержимого. Ниже приведен список различных типов объектов-рисунков.
GeometryDrawing — Выводит фигуру.
ImageDrawing — Выводит изображение.
GlyphRunDrawing — Выводит текст.
VideoDrawing — Воспроизводит аудио-или видео.
DrawingGroup — Выводит другие рисунки. Для объединения рисунков в один составной используйте группирование рисунков.
Дополнительные сведения о Drawing объектов, см. в разделе Обзор объектов Drawing.
Как и ImageBrush, DrawingBrush растягивает его Drawing для заполнения области вывода. Это поведение можно переопределить, изменив Stretch свойства из значения по умолчанию Fill. Дополнительные сведения см. в описании свойства Stretch.
Пример Заполнение объекта с помощью рисунка
В следующем примере показано, как можно заполнить объект с помощью рисунка с изображением трех эллипсов. Объект GeometryDrawing используется для описания эллипсов.
<Button Content="A Button">
<Button.Background>
<DrawingBrush>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="LightBlue">
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry RadiusX="12.5" RadiusY="25" Center="25,50" />
<EllipseGeometry RadiusX="12.5" RadiusY="25" Center="50,50" />
<EllipseGeometry RadiusX="12.5" RadiusY="25" Center="75,50" />
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Thickness="1" Brush="Gray" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Button.Background>
</Button>
// Create a DrawingBrush.
DrawingBrush myDrawingBrush = new DrawingBrush();
// Create a drawing.
GeometryDrawing myGeometryDrawing = new GeometryDrawing();
myGeometryDrawing.Brush = Brushes.LightBlue;
myGeometryDrawing.Pen = new Pen(Brushes.Gray, 1);
GeometryGroup ellipses = new GeometryGroup();
ellipses.Children.Add(new EllipseGeometry(new Point(25,50), 12.5, 25));
ellipses.Children.Add(new EllipseGeometry(new Point(50,50), 12.5, 25));
ellipses.Children.Add(new EllipseGeometry(new Point(75,50), 12.5, 25));
myGeometryDrawing.Geometry = ellipses;
myDrawingBrush.Drawing = myGeometryDrawing;
Button myButton = new Button();
myButton.Content = "A Button";
// Use the DrawingBrush to paint the button's background.
myButton.Background = myDrawingBrush;
Закрашивание области с помощью Visual
Наиболее гибкая и мощная из всех кистей, VisualBrush закрашивает область с Visual. Объект Visual является низкоуровневым графическим типом, который служит в качестве предка для многих полезных графических компонентов. Например Window, FrameworkElement, и Control классы представляют собой различные типы Visual объектов. С помощью VisualBrush, им можно рисовать заполнить область практически любым Windows Presentation Foundation (WPF) графического объекта.
Note
Несмотря на то что VisualBrush — это разновидность Freezable объекта, он не может быть заморожен (доступным только для чтения) при его Visual свойству присвоено значение, отличное от null
.
Существует два способа задания Visual содержимое VisualBrush.
Создайте новый Visual и использовать его для задания Visual свойство VisualBrush. Например, см. в разделе пример: Заполнение объекта с помощью Visual в следующем разделе.
Использовать существующее Visual, который создает дубликат изображения целевого объекта Visual. Затем можно использовать VisualBrush для создания интересных эффектов, например отражения и увеличения. Например, см. в разделе пример: Создание отражения раздел.
При определении нового Visual для VisualBrush и что Visual — UIElement (например, панель или элемент управления), система разметки выполняется UIElement и его дочерних элементов при AutoLayoutContent свойству true
. Однако корневой UIElement фактически изолирован от остальной части системы: стили и внешний макет не могут перейти эту границу. Таким образом, следует явно указать размер корневого UIElement, так как его единственным родительским объектом является VisualBrush и таким образом его размер не может автоматически подобран по заполняемой области. Дополнительные сведения о макете в Windows Presentation Foundation (WPF) см. в разделе Макет.
Как и ImageBrush и DrawingBrush, VisualBrush растягивает свое содержимое до заполнения области вывода. Это поведение можно переопределить, изменив Stretch свойства из значения по умолчанию Fill. Дополнительные сведения см. в описании свойства Stretch.
Пример Заполнение объекта с помощью Visual
В следующем примере несколько элементов управления и панель используются для заполнения прямоугольника.
<Rectangle Width="150" Height="150" Stroke="Black" Margin="5,0,5,0">
<Rectangle.Fill>
<VisualBrush>
<VisualBrush.Visual>
<StackPanel Background="White">
<Rectangle Width="25" Height="25" Fill="Red" Margin="2" />
<TextBlock FontSize="10pt" Margin="2">Hello, World!</TextBlock>
<Button Margin="2">A Button</Button>
</StackPanel>
</VisualBrush.Visual>
</VisualBrush>
</Rectangle.Fill>
</Rectangle>
VisualBrush myVisualBrush = new VisualBrush();
// Create the visual brush's contents.
StackPanel myStackPanel = new StackPanel();
myStackPanel.Background = Brushes.White;
Rectangle redRectangle = new Rectangle();
redRectangle.Width = 25;
redRectangle.Height =25;
redRectangle.Fill = Brushes.Red;
redRectangle.Margin = new Thickness(2);
myStackPanel.Children.Add(redRectangle);
TextBlock someText = new TextBlock();
FontSizeConverter myFontSizeConverter = new FontSizeConverter();
someText.FontSize = (double)myFontSizeConverter.ConvertFrom("10pt");
someText.Text = "Hello, World!";
someText.Margin = new Thickness(2);
myStackPanel.Children.Add(someText);
Button aButton = new Button();
aButton.Content = "A Button";
aButton.Margin = new Thickness(2);
myStackPanel.Children.Add(aButton);
// Use myStackPanel as myVisualBrush's content.
myVisualBrush.Visual = myStackPanel;
// Create a rectangle to paint.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 150;
myRectangle.Height = 150;
myRectangle.Stroke = Brushes.Black;
myRectangle.Margin = new Thickness(5,0,5,0);
// Use myVisualBrush to paint myRectangle.
myRectangle.Fill = myVisualBrush;
Пример Создание отражения
В предыдущем примере показано, как создать новый Visual для использования в качестве фона. Можно также использовать VisualBrush для отображения существующего визуального; эта возможность позволяет создавать интересные визуальные эффекты, например отражения и увеличения. В следующем примере используется VisualBrush для создания отражения Border , содержащего несколько элементов. На следующей иллюстрации показан результат выполнения этого примера.
Отраженный объект Visual
using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.IO;
using System.Collections.ObjectModel;
using System.Windows.Shapes;
namespace SDKSample
{
public partial class ReflectionExample : Page
{
public ReflectionExample()
{
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
this.Background = Brushes.Black;
StackPanel myStackPanel = new StackPanel();
myStackPanel.Margin = new Thickness(50);
Border myReflectedBorder = new Border();
this.RegisterName("ReflectedVisual", myReflectedBorder);
// Create a gradient background for the border.
GradientStop firstStop = new GradientStop();
firstStop.Offset = 0.0;
Color firstStopColor = new Color();
firstStopColor.R = 204;
firstStopColor.G = 204;
firstStopColor.B = 255;
firstStopColor.A = 255;
firstStop.Color = firstStopColor;
GradientStop secondStop = new GradientStop();
secondStop.Offset = 1.0;
secondStop.Color = Colors.White;
GradientStopCollection myGradientStopCollection = new GradientStopCollection();
myGradientStopCollection.Add(firstStop);
myGradientStopCollection.Add(secondStop);
LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush();
myLinearGradientBrush.StartPoint = new Point(0, 0.5);
myLinearGradientBrush.EndPoint = new Point(1, 0.5);
myLinearGradientBrush.GradientStops = myGradientStopCollection;
myReflectedBorder.Background = myLinearGradientBrush;
// Add contents to the border.
StackPanel borderStackPanel = new StackPanel();
borderStackPanel.Orientation = Orientation.Horizontal;
borderStackPanel.Margin = new Thickness(10);
TextBlock myTextBlock = new TextBlock();
myTextBlock.TextWrapping = TextWrapping.Wrap;
myTextBlock.Width = 200;
myTextBlock.Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit." +
" Suspendisse vel ante. Donec luctus tortor sit amet est." +
" Nullam pulvinar odio et wisi." +
" Pellentesque quis magna. Sed pellentesque." +
" Nulla euismod." +
"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.";
borderStackPanel.Children.Add(myTextBlock);
StackPanel ellipseStackPanel = new StackPanel();
Ellipse ellipse1 = new Ellipse();
ellipse1.Margin = new Thickness(10);
ellipse1.Height = 50;
ellipse1.Width = 50;
ellipse1.Fill = Brushes.Black;
ellipseStackPanel.Children.Add(ellipse1);
Ellipse ellipse2 = new Ellipse();
ellipse2.Margin = new Thickness(10);
ellipse2.Height = 50;
ellipse2.Width = 50;
ellipse2.Fill = Brushes.Black;
ellipseStackPanel.Children.Add(ellipse2);
Ellipse ellipse3 = new Ellipse();
ellipse3.Margin = new Thickness(10);
ellipse3.Height = 50;
ellipse3.Width = 50;
ellipse3.Fill = Brushes.Black;
ellipseStackPanel.Children.Add(ellipse3);
borderStackPanel.Children.Add(ellipseStackPanel);
myReflectedBorder.Child = borderStackPanel;
// Create divider rectangle
Rectangle dividerRectangle = new Rectangle();
dividerRectangle.Height = 1;
dividerRectangle.Fill = Brushes.Gray;
dividerRectangle.HorizontalAlignment = HorizontalAlignment.Stretch;
// Create the object to contain the reflection.
Rectangle reflectionRectangle = new Rectangle();
// Bind the height of the rectangle to the border height.
Binding heightBinding = new Binding();
heightBinding.ElementName = "ReflectedVisual";
heightBinding.Path = new PropertyPath(Rectangle.HeightProperty);
BindingOperations.SetBinding(reflectionRectangle, Rectangle.HeightProperty, heightBinding);
// Bind the width of the rectangle to the border width.
Binding widthBinding = new Binding();
widthBinding.ElementName = "ReflectedVisual";
widthBinding.Path = new PropertyPath(Rectangle.WidthProperty);
BindingOperations.SetBinding(reflectionRectangle, Rectangle.WidthProperty, widthBinding);
// Creates the reflection.
VisualBrush myVisualBrush = new VisualBrush();
myVisualBrush.Opacity = 0.75;
myVisualBrush.Stretch = Stretch.None;
Binding reflectionBinding = new Binding();
reflectionBinding.ElementName = "ReflectedVisual";
BindingOperations.SetBinding(myVisualBrush, VisualBrush.VisualProperty, reflectionBinding);
ScaleTransform myScaleTransform = new ScaleTransform();
myScaleTransform.ScaleX = 1;
myScaleTransform.ScaleY = -1;
TranslateTransform myTranslateTransform = new TranslateTransform();
myTranslateTransform.Y = 1;
TransformGroup myTransformGroup = new TransformGroup();
myTransformGroup.Children.Add(myScaleTransform);
myTransformGroup.Children.Add(myTranslateTransform);
myVisualBrush.RelativeTransform = myTransformGroup;
reflectionRectangle.Fill = myVisualBrush;
// Create a gradient background for the border.
GradientStop firstStop2 = new GradientStop();
firstStop2.Offset = 0.0;
Color c1 = new Color();
c1.R = 0;
c1.G = 0;
c1.B = 0;
c1.A = 255;
firstStop2.Color = c1;
GradientStop secondStop2 = new GradientStop();
secondStop2.Offset = 0.5;
Color c2 = new Color();
c2.R = 0;
c2.G = 0;
c2.B = 0;
c2.A = 51;
firstStop2.Color = c2;
GradientStop thirdStop = new GradientStop();
thirdStop.Offset = 0.75;
Color c3 = new Color();
c3.R = 0;
c3.G = 0;
c3.B = 0;
c3.A = 0;
thirdStop.Color = c3;
GradientStopCollection myGradientStopCollection2 = new GradientStopCollection();
myGradientStopCollection2.Add(firstStop2);
myGradientStopCollection2.Add(secondStop2);
myGradientStopCollection2.Add(thirdStop);
LinearGradientBrush myLinearGradientBrush2 = new LinearGradientBrush();
myLinearGradientBrush2.StartPoint = new Point(0.5, 0);
myLinearGradientBrush2.EndPoint = new Point(0.5, 1);
myLinearGradientBrush2.GradientStops = myGradientStopCollection2;
reflectionRectangle.OpacityMask = myLinearGradientBrush2;
BlurBitmapEffect myBlurBitmapEffect = new BlurBitmapEffect();
myBlurBitmapEffect.Radius = 1.5;
reflectionRectangle.BitmapEffect = myBlurBitmapEffect;
myStackPanel.Children.Add(myReflectedBorder);
myStackPanel.Children.Add(dividerRectangle);
myStackPanel.Children.Add(reflectionRectangle);
this.Content = myStackPanel;
}
/*
<Rectangle
Height="{Binding Path=ActualHeight, ElementName=ReflectedVisual}"
Width="{Binding Path=ActualWidth, ElementName=ReflectedVisual}">
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#FF000000" Offset="0.0" />
<GradientStop Color="#33000000" Offset="0.5" />
<GradientStop Color="#00000000" Offset="0.75" />
</LinearGradientBrush>
</Rectangle.OpacityMask>
<Rectangle.BitmapEffect>
<BlurBitmapEffect Radius="1.5" />
</Rectangle.BitmapEffect>
</Rectangle>
</StackPanel>
</Page>
*/
}
}
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Black">
<StackPanel Margin="50">
<!-- The object to reflect. -->
<Border Name="ReflectedVisual" Width="400">
<Border.Background>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<GradientStop Offset="0.0" Color="#CCCCFF" />
<GradientStop Offset="1.0" Color="White" />
</LinearGradientBrush>
</Border.Background>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock TextWrapping="Wrap" Width="200" Margin="10">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Suspendisse vel ante. Donec luctus tortor sit amet est.
Nullam pulvinar odio et wisi.
Pellentesque quis magna. Sed pellentesque.
Nulla euismod.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
</TextBlock>
<StackPanel>
<Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
<Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
<Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
</StackPanel>
</StackPanel>
</Border>
<Rectangle Height="1" Fill="Gray" HorizontalAlignment="Stretch" />
<!-- The object to contain the reflection.-->
<Rectangle
Height="{Binding Path=ActualHeight, ElementName=ReflectedVisual}"
Width="{Binding Path=ActualWidth, ElementName=ReflectedVisual}">
<Rectangle.Fill>
<!-- Creates the reflection. -->
<VisualBrush
Opacity="0.75" Stretch="None"
Visual="{Binding ElementName=ReflectedVisual}">
<VisualBrush.RelativeTransform>
<!-- Flip the reflection. -->
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="-1" />
<TranslateTransform Y="1" />
</TransformGroup>
</VisualBrush.RelativeTransform>
</VisualBrush>
</Rectangle.Fill>
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#FF000000" Offset="0.0" />
<GradientStop Color="#33000000" Offset="0.5" />
<GradientStop Color="#00000000" Offset="0.75" />
</LinearGradientBrush>
</Rectangle.OpacityMask>
<Rectangle.BitmapEffect>
<BlurBitmapEffect Radius="1.5" />
</Rectangle.BitmapEffect>
</Rectangle>
</StackPanel>
</Page>
Дополнительные примеры, демонстрирующие увеличение частей экрана и создание отражений, см. в разделе Пример VisualBrush.
Функции TileBrush
ImageBrush, DrawingBrush, и VisualBrush типов TileBrush объектов. TileBrush объекты предоставляют высокую степень контроля над закрашивание области с изображения, рисунок или visual. Например, можно заполнить область не одним растянутым изображением, а элементами мозаики, которые образуют узор.
Объект TileBrush имеет три основных компонента: содержимое, плитки и область вывода.
Компоненты TileBrush с одним элементом мозаики
Компоненты TileBrush с несколькими элементами мозаики
Дополнительные сведения о функциях мозаики из TileBrush объектов, см. в разделе Общие сведения о TileBrush.
См. также
- ImageBrush
- DrawingBrush
- VisualBrush
- TileBrush
- Общие сведения о TileBrush
- Общие сведения о кистях WPF
- Общие сведения об обработке изображений
- Обзор объектов Drawing
- Общие сведения о масках непрозрачности
- Общие сведения об отрисовке графики в WPF
- Пример использования кистей
- Пример использования VisualBrush