14_Березина_2DГрафика

advertisement
Классы двумерной графики WPF
System.Object
DispatcherObject
DependencyObject
DrawingContext
Visual
Freezable
UIElement
FrameworkElement
Shape
Image
Animatable
Brush
Pen
GradientBrush
Geometry
ImageSource
PathSegment
PathFigure
Drawing
CombinedGeometry
DrawingImage
DrawingGroup
BitmapSource
ImageDrawing
Ellipse
LineGradientBrush
EllipseGeometry
Line
RadialGradientBrush
GeometryGroup
BitmapFrame
ArcSegment
GeometryDrawing
…
Path
SolidColorBrush
LineGeometry
BitmapImage
BezierSegment
Polygon
TileBrush
PathGeometry
CroppedBitmap
LineSegment
…
Polyline
DrawingBrush
RectangleGeometry
Rectangle
ImageBrush
StreamGeometry
ContainerVisual
DrawingVisual
VisualBrush
PolyBezierSegment
PolyLineSegment
PolyQuadraticBezierSegment
QuadraticBezierSegment
Графическая система WPF
 Графическая система приложений на основе GDI или GDI+ использует режим
интерпретации – за обновление(перерисовку) отвечает приложение.
 Графическая система WPF использует сохраненный режим:
• объекты приложения, имеющие визуальное представление, определяют набор
сериализованных графических данных;
• после определения графических данных за перерисовку объектов приложения
отвечает система.
 В WPF для всех элементов реализована композитная система рендеринга. Операции
рисования выполняются с самого нижнего ( минимальное значение z-индекса) элемента.
Более близкие к наблюдателю элементы перекрывают выведенные ранее.
Единицы измерения WPF
 WPF использует аппаратно-независимую единицу 1/96 дюйма (логический пиксель).
 Если стандартный параметр системы DPI равен 96 dpi, аппаратно-независимая единица
соответствует одному физическому пикселю, так как
размер физической единицы = размер аппаратно-независимой единицы x DPI системы
 Если установить в системе другое значение DPI, например, 120 (крупный шрифт),
размер физической единицы будет равен 1/96*120 = 1.25 (пикселей). Размер всех
элементов управления, текста, любых изображений увеличится.
 Пункт(point) 1/72 дюйма.
 Технология совмещения с пикселями - pixel snapping
Классы Shape и Geometry
 Классы, производные от абстрактного базового класса System.Windows.Media.Geometry,
определяют геометрические фигуры. Класс Geometry определяет только геометрию фигуры
( координаты и размер), и сам себя отображать не может.
 Классы, производные от System.Windows.Shapes.Shape,
• поддерживают события, как и другие элементы управления;
• участвуют в системе макета, их можно разместить в любой контейнер компоновки;
• автоматически перерисовываются при изменении размера, перемещении или
изменении свойств.
 Класс Shape содержит ссылку на объект Geometry:
public virtual Geometry RenderedGeometry { get; }
 Свойство Data класса Path (производный от Shape) возвращает или задает объект
Geometry, определяющий фигуру для рисования:
public Geometry Data { get; set; }
Фигуры(shape)
Visual
 Некоторые свойства, определенные в классе Shape:
UIElemrnt
FrameworkElement
Shape
Ellipse
Line
Path
Polyline
Polygon
Rectangle
Image
public Brush Fill { get; set; }
Объект Brush для внутренней части
фигуры. Умолчание null.
public Brush Stroke { get; set; }
Объект Brush для контура фигуры.
Умолчание null.
public double StrokeThickness
{ get; set; }
Толщина контура.
public Stretch Stretch { get; set; } Способ заполнения выделенного
для фигуры пространства.
Перечисление Stretch имеет
значения None, Fill, Uniform,
UniformToFill.
System.Windows.Shapes.Line
 Элемент управления, представляющий собой отрезок прямой, соединяющий две точки.
 Свойства класса Line, которые задают отрезок прямой. Координаты задаются
относительно левого верхнего угла контейнера размещения без полей.
public double X1 { get; set; }
public double Y1 { get; set; }
public double X2 { get; set; }
public double Y2 { get; set; }
 Пример определения в разметке
<Grid Grid.Column="1" Background="WhiteSmoke">
<Line Name="line_right" Margin ="10,10,10,10“
X1="0" Y1="0" X2="100" Y2="100"
Stroke="SlateBlue" StrokeThickness="2">
</Line>
</Grid>
 Пример в коде C#.
public partial class Page_Lines : Page
{ Line line_left = new Line();
private void Page_Loaded(object sender, RoutedEventArgs e)
{
line_left.X1 = 10;
line_left.Y1 = 10;
line_left.X2 = 100;
line_left.Y2 = 150;
line_left.Stroke = new SolidColorBrush(Colors.Red);
line_left.StrokeThickness = 1;
}
if (grid1.Children.Contains(line_left) == false)
grid1.Children.Add(line_left);
…………
System.Windows.Shapes.Polyline
 Элемент управления, представляющий собой линию, состоящую из отрезков прямой.
 Класс содержит коллекцию, состоящую из вершин Polyline.
public PointCollection Points { get; set; }
 Коллекция PointCollection
[TypeConverterAttribute(typeof(PointCollectionConverter))]
public sealed class PointCollection : Freezable, IFormattable, IList,
ICollection, IList<Point>, ICollection<Point>,
IEnumerable<Point>, IEnumerable
 При объявлении коллекции PointCollection в разметке можно использовать обычный
синтаксис для коллекций или задать в виде строки, в которой координаты вершин
разделены одной запятой и (или) одним или несколькими пробелами.
 Пример объявления в разметке
< Grid Grid.Column="1" Background="WhiteSmoke">
<Polyline Name="polyline_1" Margin ="10,10,10,10"
Points="10,10,50,100,100,100,150,10,200,150,250,0"
Stroke="SlateBlue" StrokeThickness="1"></Polyline>
<Polyline Name="polyline_2" Margin ="10,10,10,10"
Points="10,30 50,120 100,120 150,30 200,170 250,20"
Stroke="Red" StrokeThickness="1"></Polyline>
</Grid>
Классы Path, Geometry и PathGeometry
 Класс PathGeometry представляет
фигуру, которая может состоять из
дуг, кривых, эллипсов, линий и
прямоугольников.
System.Object
DispatcherObject
DependencyObject
 Каждый объект PathGeometry
содержит коллекцию объектов
PathFigure, доступную через свойство
Figures:
Freezable
Animatable
public PathFigureCollection Figures { get; set; }
Geometry
PathSegment
PathFigure
CombinedGeometry
ArcSegment
EllipseGeometry
BezierSegment
GeometryGroup
LineSegment
 Каждый объект PathFigure
содержит коллекцию объектов
PathSegment, (ArcSegment,
BezierSegment , …), доступную
через свойство Segments:
public PathSegmentCollection Segments { get; set; }
LineGeometry
PolyLineSegment
PathGeometry
PolyBezierSegment
RectangleGeometry
StreamGeometry
QuadraticBezierSegment
PolyQuadraticBezierSegment
Объект PathGeometry можно
отобразить с помощью элемента
Path:
В классе Path есть свойство
public Geometry Data { get; set; }
Класс Geometry
Объекты Geometry поддерживают отсечение и проверку нажатия.
 Следующие методы класса проверяют, содержит ли вызывающий объект Geometry
заданный объект.
public bool
FillContains( Geometry geometry );
Проверяет, содержит ли вызывающий объект
Geometry заданный объект Geometry (целиком).
public bool
FillContains( Point hitPoint );
Проверяет, содержит ли вызывающий объект
Geometry заданный объект Point.
public bool
FillContains( Geometry geometry,
double tolerance, ToleranceType type );
Проверяет, содержит ли вызывающий объект
Geometry заданный объект Geometry с учетом
заданного предела погрешности.
public bool
FillContains( Point hitPoint,
double tolerance, ToleranceType type );
Проверяет, содержит ли вызывающий объект
Geometry заданный объект Point с учетом
заданного предела погрешности.
 В классе определен метод Parse который позволяет задать геометрию в виде строки.
public static Geometry Parse( string source );
 При заполнении области PathGeometry ко всем объектам PathFigure, свойство IsFilled
которых имеет значение true, применяется правило FillRule.
Создание составных фигур
 Геометрии можно комбинировать с помощью
• класса GeometryGroup,, который создает составную геометрию из любого числа
объектов Geometry;
• класса CombinedGeometry, который создает составную геометрию из двух объектов
Geometry и при объединении использует заданную двоичную операцию;
• статического метода Combine класса Geometry (дублирует возможности класса
CombinedGeometry).
static PathGeometry Combine ( Geometry geometryA, Geometry geometryB,
GeometryCombineMode mode, Transform transform );
 Перечисление GeometryCombineMode имеет значения
Union
объединение
Intersect
пересечение
Xor
(A-B) + (B-A)
Exclude
A-B
Класс Transform
System.Object
DispatcherObject
 Transform – абстрактный базовый класс для
преобразований в двухмерной плоскости.
TranslateTransform
Перенос.
RotateTransform
Поворот.
ScaleTransform
Масштабирование.
SkewTransform
Отклонение.
MatrixTransform
Пользовательские
преобразования.
TransformGroup
Объединение нескольких
объектов Transform в составной
объект.
DependencyObject
Freezable
Animatable
GeneralTransform
Transform
MatrixTransform
RotateTransform
ScaleTransform
SkewTransform
TransformGroup
TranslateTransform
GeneralTransformGroup
 В производных от Transform классах определены
свойства, с помощью которых можно задать
параметры конкретных преобразований.
 В классе TransformGroup определена коллекция
объектов Transform
public TransformCollection Children { get; set; }
Структура System.Windows.Media.Matrix
 Представляет матрицу 3x3 аффинного преобразования в двухмерном пространстве.
Элементы матриц можно задать с помощью свойств типа double
M11
M12
0
M21
M22
0
OffsetX
OffsetY
1
 В типе Matrix определен конструктор
public Matrix ( double m11, double m12, double m21, double m22, double offsetX, double offsetY );
и метод Parse , который преобразует строку (шесть значений double, разделенных
запятыми) в объект Matrix.
public static Matrix Parse( string source );
 Методы Transform, определенные в Matrix, преобразуют заданную точку, массив точек,
вектор или массив векторов с использованием вызывающей структуры Matrix.
public Point Transform ( Point point );
public void Transform ( Point[] points );
public Vector Transform ( Vector vector );
public void Transform ( Vector[] vectors );
 System.Windows.Vector – структура с двумя полями типа double, которые доступны через
свойства X и Y. Представляет смещение в двумерном пространстве.
Операции с Matrix
 В типе Matrix определены методы преобразований, которые можно свести к умножению
исходной (вызывающей) матрицы на матрицу специального вида. Так как умножение матриц
некоммутативно, для каждого типа преобразований определены два метода – для
умножения заданной матрицы на исходную матрицу слева и справа. Методы, в которых
первым выполняется новое преобразование, имеют в своем названии корень Prepend.
public static Matrix Multiply
( Matrix trans1, Matrix trans2 );
Умножение матриц.
public void Append( Matrix matrix );
Умножение исходной матрицы на заданную матрицу
справа.
public void Prepend( Matrix matrix );
Умножение исходной матрицы на заданную матрицу
слева.
public void SetIdentity();
Преобразование исходной матрицы в единичную
матрицу.
public bool HasInverse { get; }
Проверка, что матрица является обратимой.
public void Invert();
Замена исходной матрицы на обратную.
Перенос, поворот и масштабирование в Matrix
 В приведенных ниже методах первым выполняется преобразование, которое
определяется вызывающим объектом Matrix.
public void Translate
( double offsetX, double offsetY );
Перенос Matrix на заданное смещение.
public void Rotate( double angle );
Поворот Matrix на заданный (в градусах)
угол вокруг начала координат.
public void RotateAt ( double angle,
double centerX, double centerY );
Поворот Matrix на заданный (в градусах)
угол вокруг заданной точки.
public void Scale( double scaleX, double scaleY );
Масштабирование Matrix на заданную
величину.
public void ScaleAt( double scaleX, double scaleY,
double centerX, double centerY );
Масштабирование Matrix на заданную
величину относительно заданной точки.
public void Skew ( double skewX, double skewY );
Прибавляет отклонение на заданное
значение по осям X и Y в конец данной
структуры Matrix.
 В типе Matrix также определены методы TranslatePrepend, RotatePrepend, RotateAtPrepend,
ScalePrepend, ScaleAtPrepend, SkewPrepend с такими же параметрами, как и методы без
корня Prepend. В этих методах первым выполняется преобразование, которое определяется
значениями параметров.
Некоторые свойства и методы класса Transform
public static Transform Identity
{ get; }
Возвращает единичное преобразование.
public abstract Matrix Value
{ get; }
Возвращает текущее преобразование как объект Matrix.
public static Transform Parse
( string source );
Создает новый объект Transform из матрицы
преобразования, заданной в текстовом виде ( шесть
значений double, разделенных запятыми).
public Point
Transform( Point point );
Выполняет преобразование для заданной точки. Бросает
исключение, если преобразование завершилось
неудачей.
public override bool
TryTransform ( Point inPoint,
out Point result ):
Выполняет преобразование для заданной точки и
возвращает true, если преобразование выполнено
успешно. В противном случае возвращает false и не
бросает исключение.
public override Rect
TransformBounds ( Rect rect );
Выполняет преобразование заданного прямоугольника и
возвращает наименьший ограничивающий прямоугольник,
содержащий преобразованный объект rect.
Классы DrawingVisual и GeometryDrawing
System.Object
DispatcherObject
DependencyObject
DrawingContext
Visual
Freezable
UIElement
FrameworkElement
Shape
Image
Ellipse
Animatable
ImageSource
Drawing
DrawingImage
DrawingGroup
BitmapSource
ImageDrawing
Line
BitmapFrame
GeometryDrawing
Path
BitmapImage
GlypgRunDrawing
Polygon
CroppedBitmap
VideoDrawing
Polyline
…
Rectangle
ContainerVisual
DrawingVisual
DrawingVisual — это визуальный
объект, который можно
использовать для отрисовки
векторной графики на экране.
Содержимое объекта сохраняется
системой.
 Класс не поддерживает разметку
и обработку событий, что
повышает его производительность.
Drawing — это упрощенные
объекты, позволяющие добавлять
геометрические фигуры,
изображения, текст и
мультимедийные данные в
приложение.
 Объекты Drawing не
поддерживают cистему макета,
ввод и фокус, что улучшает их
производительность.
Класс Visual
 Объект Visual является ядром объекта WPF.
Объект Visual обеспечивает :
• отрисовку сохраненного, сериализованного содержимого визуального объекта;
• выполнение преобразований визуального объекта;
• обеспечение поддержки отсечения области визуального объекта;
• определение принадлежности заданной координаты (точки) или геометрии к области,
занимаемой визуальным объектом;
• определение ограничивающего прямоугольника визуального объекта.
Объект Visual хранит данные визуализации в виде списка инструкций векторной графики в
сериализованном формате.
 Для оптимизации приложений с интенсивной графикой WPF предлагает модель
визуального слоя, в которой каждый графический элемент определяется как объект Visual, а
для отображения всех объектов Visual используется один элемент управления.
Класс DrawingContext
 Класс DrawingContext служит для заполнения объектов Visual (или Drawing) визуальным
содержимым. DrawingContext хранит набор инструкций отрисовки, которые позднее
использует графическая система.
 Нельзя создать экземпляр DrawingContext. Ссылку на объект DrawingContext можно
получить как возвращаемое значение методов некоторых классов, например, метода
RenderOpen класса DrawingVisual
public DrawingContext RenderOpen();
 В классе DrawingContext определены методы для команд рисования, например,
public abstract void DrawEllipse( Brush brush, Pen pen, Point center, double radiusX, double radiusY );
public void DrawText ( FormattedText formattedText, Point origin );
public abstract void DrawGeometry( Brush brush, Pen pen, Geometry geometry );
public abstract void DrawDrawing( Drawing drawing );
 Для того, чтобы сохранить содержимое DrawingContext, надо вызвать метод Close.
public abstract void Close();
 После вызова метода Close визуальный объект нельзя изменять, но можно применить
трансформацию.
Класс DrawingContext. Пример
 В примере получена ссылка на DrawingContext для объекта DrawingVisual и в объект
DrawingContext добавлен эллипс
DrawingVisual visual = new DrawingVisual();
DrawingContext dc = visual.RenderOpen();
Pen pen = new Pen(Brushes.Red, 2);
dc.DrawEllipse(Brushes.Gainsboro, pen, clickedPoint, 40, 20);
dc.Close();
 Чтобы вывести объект DrawingVisual его надо добавить в визуальное дерево некоторого
элемента. В примере объект добавлен в элемент canvas типа Canvas.
canvas.AddVisualChild(visual);
Класс DrawingContext. Пример. Продолжение
class DrawingCanvas : Canvas
{
private List<Visual> visuals = new List<Visual>();
protected override int VisualChildrenCount
{ get { return visuals.Count; }
}
protected override Visual GetVisualChild(int index)
{ return visuals[index];}
public void AddVisual(Visual visual)
{
visuals.Add(visual);
base.AddVisualChild(visual);
base.AddLogicalChild(visual);
}
public void RemoveVisual(Visual visual)
{
visuals.Remove(visual);
base.RemoveVisualChild(visual);
base.RemoveLogicalChild(visual);
}
public DrawingVisual GetVisual(Point point)
{ HitTestResult res = VisualTreeHelper.HitTest(this, point);
return res.VisualHit as DrawingVisual;
}
}
Класс Freezable
 Класс Freezable поддерживает функции, которые улучшают работу приложения с
объектами, на изменение или копирование которых тратится много ресурсов.
 Класс, производный от Freezable,
• поддерживает состояния только для чтения (фиксированный) и для чтения/записи;
• фиксированный объект Freezable безопасно использовать в нескольких потоках;
• класс сообщает об изменениях, если изменяются значения вложенных свойств;
• в классе есть методы, которые обеспечивают большую глубину клонирования.
 Нельзя зафиксировать объект Freezable, если
• объект имеет анимированные или привязанные к данным свойства;
• объект имеет свойства, значения которых установлены динамическим ресурсом;
• объект содержит подобъекты Freezable, которые нельзя зафиксировать.
 Свойство IsFrozen класса Freezable проверяет, является ли объект фиксированным. Если
попытаться изменить зафиксированный объект Freezable, будет брошено исключение
InvalidOperationException.
 В примере вызывается метод Freeze, чтобы зафиксировать объект brush .
SolidColorBrush brush = new SolidColorBrush(Colors.SlateBlue);
if (brush.CanFreeze) brush.Freeze();
Download