순서

I. Geometry Class
I. Image를 사용한 Drawing

II. Shape.Path를 사용한 Drawing

 


I. Geometry class

아래와 같이 WPF의 Canvas Panel에서 점, 선등 Geometry로 정의되는 객체
그리는는 것이다.

하지만 Drawing 할 수 있는 방법과  class가 너무 많아 헷갈리고 정보도 안나와서
해보며 공부한 것을 정리했다.

 

Geometry, GeometryDrawing, ImageDrawing, Shape, DrawingContext, Path
DrawingImage 등등

너무 비슷하지만 다른 클래스들, 그리고 사용 방법도 달라서
그리는 방법과 순서에 따라 클래스들을 정리하고자 한다.

 

도형 정의하기

  Geometry Class Shape Class  
파생 클래스
네임스페이스 Window. Media Window. Shapes  
파생 Freezable - 
Animatable - 
Geometry
UIelement -
FrameworkElement - 
Shape
 
도형들 EllipseGeometry
LineGeometry
RectangleGeometry
등등
Ellipse
Line
Rectangle
PolyLine
등등
 
도형을
그룹으로
묶기
GeometryGroup X -> 도형의 객체를
Children으로 묶을 수 있다.
-> Geometry를 상속받음
개체 특성
차이 1. 개체 자신을 그릴 수 없다.
-> Drawing 혹은 Path등을
통해 그림 속성을 정의해야함.
이 객체 자체를 그릴 수 있다.
-> 그림 속성 설정 가능
 
차이 2. 더 간단하고 가볍다.
Freezable 특징을 갖는다.
-> 객체에 대한 권한 및 접근을 컨트롤 함.
패널과 대부분 컨트롤 내부에서 다 접근 가능하다.
-> FrameworkElement파생의 특징으로 무거움
 

+) Drawing 개체도 별도로 따로 있는데 이 안에
GeometryDrawing
ImageDrawing
GlyphRunDrawing
DrawingGroup이 있고
이는 모두 Window.Media 네임스페이스에 있다.

나는 Drawing 방법 1에서 GeometryDrawing를 사용했고 이때 사용하는
DrawingImage 클래스와 위의 ImageDrawing은 다른 것이다!

 


II. Drawing 방법 1 - Image

 

Geometry(GeometryGroup) → GeometryDrawing →
DrawingImage → Canvas Image

Shape는 그 자체로 Drawing 특성을 정의할 수 있었다.
그렇다면 더 가벼운 Geometry Class를 Canvas에 렌더링 하는 방법은 뭐가 있을까.

우선 기본적으로 Windows.System에 Point라는 객체가 있다는 것을 알자.
Point (double X, double Y)
(+X : → 방향, +Y : ↓ 방향)

 

Step1. Geometry -> GeometryGroup class로 묶기 (선택)

동시에 여러 Geometry를 그린다는 가정 하에 그룹으로 묶어보자.

단일 Geometry만 그릴 것이라면 Group화 하지 않아도 된다.

double X0, Y0 = 0;
double X1, Y1 = 100;

GeometryGroup gG = new GeometryGroup();

// EllipaseGeometry ( Point, radiusX, radiusY )
EllipseGeometry E = new EllipseGeometry(new Point(X0,Y0), 2, 2);

// PathGeometry (Point from, Point to)
LineGeometry L = new LiseGeometry(new Point(X0,Y0), new Point(X1,Y1));

// 2개의 Geometry를 Group으로 묶기
gG.Children.Add(E);
gG.Children.Add(L);

 

Step2. 그릴방법을 정의하기 위한 GeometryDrawing class 생성

 

Geometry 혹은 GeometryGroup을 Drawing객체로 만들 수 있다.
 GeometryDrawing class에서 실제로 Pen, Brush등 그릴 방법을 정의한다.

System.Windows.Media에
윤곽선을 그리는 Pen 클래스와
내부를 칠하는 Brush 클래스가 정의되어 있다.
그리고 색깔을 정의하기 위해 Brushes 클래스도 있다.

GeometryDrawing gD = new GeometryDrawing();

gD.Pen = new Pen(Brushes.Black, 2);
gD.Brush = Brushes.DarkRed;

// 위에서 저장한 GeometryGroup
// 단일 Geometry만 넣어도 된다.
gD.Geometry = gG

 

GeometryDrawing은 위 코드에서 정의한 3가지를 지원한다.

 

Step3. Image로 변환하기 위한 DrawingImage class 생성 

 

우린 GeometryDrawing을 만들었고, 이건 그릴 방법이지 형식이 아니다.

따라서 Image형식으로 가지고 있는 DrawingImage class를 만들어서 지정 해주어야 한다.

// gD : 위에서 만든 GeometryDrawing
DrawingImage = new DrawingImage(gD)

 

DrawingImage는 위와같이 정의되어 있고,
Parameter로 들어가는 Drawing이 Animatable class를 상속 받기 때문에
동일하게 Animatable로 부터 상속받은 GeometryDrawing을 매개변수로 넣을 수 있다.

 


+) 추가 설명

맨 위의 표에서 적었지만 파생관계가
DrawingClass → ImageDrawing class와는 다르다!

Animatable → DrawingSource → DrawingImage
Animatable → Drawing → ImageDrawing
이고

우리가 위에서 사용한 GeometryDrawing
Animatable → Drawing → GeometryDrawing이다.
헷갈리지 말자.

즉, ImageDrawing, GeometryDrawing은 동일한 Layer이고
DrawingImage는 다른 Layer이다.

하지만 모두 Window. Media Namespace임은 동일하다.


 

Step4. WPF Image source로 DrawingImage를 지정하기

이제 실제로 WPF에 만들어둔 Canvas Panel안에 Image를 생성하여 지정해주면 된다.

test. xaml

x:Name = "image"로 코드 비하인드와 연결하고

// Soruce를 위에서 만든 DrawingImage 객체로 할당
image.Source = dI;

// 가시성 속성 저장
image.Visibility = Visibility.Visible;

 

Step5. Update하기

총 클래스 생성 과정을 정리해보면

Geometry(GeometryGroup) → GeometryDrawing →
DrawingImage → Image로 최종 연결하였다.

만약 그림을 추가, 삭제 등 Update할 때 항상
위의 모든 과정을 거쳐야 할까?

정답은 그럴 필요 없고 GeometryGroup만 변경해주면 된다!

C#의 객체들은 기본적으로 참조를 가지고 있다. (C++의 포인터개념)
따라서 실제로 그릴 객체를 저장하고 있는 GeometryGroup만
추가, 삭제 해준다면 Image의 업데이트가 자동으로 진행된다.

예시) 마우스 클릭하면 그 위치에 점이 생기는 코드

마우스 왼쪽 클릭할 때 이벤트

단순히 _gG (GeometryGroup). Children.Add를 해줄 뿐이고,
Image가 실시간으로 변경(점이 추가) 된다.

 

+) Image로 했을 때 문제점

아마 해보면 내가 원하는 Point에 찍히지 않을 것이고,
Pannel 특성에 따라 자동으로 사이즈가 조절 될 것이다.

이 이유는 이미지로 만들어서 넣는 방법은 실제로 렌더링을 내가 하는 것이 아닌
렌더링 된 이미지를 패널에 단지 붙이는 것이기 때문이다.

 


II. Shape.Path를 사용한 Drawing

Shape Class는 자체적으로 Drawing 방법을 제공한다.

...작성 중

 

+ Recent posts