언제였지, 기억도 않나네.. 그렇다고 오래된 사진도 아닌데.. 최소 1달 이내의 사진. 회사 워크샵때 양평 용문산으로 등산. 회사 입사해서 하는 첫 등산. 입사하기전에 등산 꽤 자주 갔었는데.. 회사 핑계로 등산 못갔는데, 회사 덕에 드뎌 등산을 하게된 것이다. 이번주 토요일에 수락산으로 모처럼 등산을 가야겠다. 머리 식힐 겸해서 오랜만에 사진 하나 가볍게 올려봄..
Brush for WPF
WPF의 2D Graphic의 효과 중에 채움(Fill) 효과에 대한 것이다. WPF의 채움은 Brush라는 개념으로 이루어지며 다음과 같은 종류가 있다.
- SolidColorBrush
- LinearGradientBrush
- RadialGradientBrush
- ImageBrush
- DrawingBrush
- VisualBrush
SolidBrush는 Geometry에 대해 단색으로 칠하는 브러쉬이고 LinearGradientBrush는 Gradient 색상을 선형으로 생성하여 채워준다. 또한 RadialGradientBrush는 방사형으로 Gradient 색상을 생성하여 채워주며 ImageBrush는 Image를 이용해 원하는 Geometry의 안을 채워준다. 그리고 DrawingBrush는 채우기 위한 내용을 사용자가 직접 또 다른 Geometry를 이용하여 만들어 채울 수 있다. 마지막으로 VisualBrush는 Control 등과 같은 내용(Content)를 이용하여 그 UI의 외형을 Geometry에 채울 수 있는 브러쉬이다. 참고로 브러쉬는 2차원뿐만이 아니라 3차원에서도 사용할 수 있다.
그럼 6개의 브러쉬에 대해 하나 하나 살펴 보기로 하자.
Geometry는 Rectangle이고 총 4개를 화면상에 렌더링했으며 Geometry의 Fill을 위해 SolidColorBrush를 사용하였다. 채움색의 지정을 위해 Color 속성을 사용하였고 투명도를 위해 Opacity를 사용하였다.
마찬가지로 Rectangle Geometry를 이용하여 화면상에 총 4개를 그렸다. 여러개의 GradientStop Element를 사용해서 선형으로 생성할 Gradient 색상을 단계적으로 지정할 수 있다.
방사형의 Gradient 색상을 생성하는 것으로 RadialGradientBrush Element를 사용하였고 방사형의 중심을 지정하기 위해 GradientOrigin을 사용하였다. GradientOrigin의 밤위는 0~1 사이의 실수값이다. LinearGradientBrush와 마찬가지로 다수의 GradientStop을 사용하여 색상과 Offset 위치를 지정할 수 있다. 효과적인 방사형의 Gradient 적용을 살펴보기 위해 Geometry로 Ellipse를 사용해보았다.
이미지를 이용하여 Geometry를 채우는 것으로써 Geometry의 크기에 맞게 이미지를 키울 수 도 있고, 키우지 않고 원래 크기대로 채워 그릴 수도 있으며, 타일형식으로 채워 넣을 수도 있다. 사용하는 Element는 ImageBrush이다.
Effect가 적용된 Geometry 자체를 채움을 위한 브러쉬로써 사용할 수 있는 DrawingBrush Element의 사용예이다. 앞서 사용했던 다양한 Brsuh들이 적용된 Geometry가 다시 Brush로써 사용되는 것을 알 수 있다.
Hello, World! Hello, World! Hello, World!
마지막으로 가장 융통성이 뛰어난 VisualBrush이다. Control은 물론이거니와 DrawingBrush의 기능까지도 포함할 수 있는 브러쉬로써 3차원으로 렌더링된 장면까지도 담을 수 있는 Brush이다. 또한 이 브러쉬를 이용하면 3차원 장면에서 2D GUI를 활용할 수 있게 하는 가장 화려한 브러쉬이다.
2D Geometry in WPF
Path를 이용한 Geometry를 렌더링 하는 가장 간단한 코드이다. Rectangle Geometry를 나타내고 있다. Path Element의 속성으로써 Stroke와 Fill을 줄 수 있는데, Stroke는 외곽선의 색상을 의미하고 Fill은 채움색을 의미한다. StrokeThickness는 외곽선의 굵기값이다.
Path를 이용한 Geometry를 렌더링하는 코드로써 여러개의 Geometry를 하나의 Geometry로 묶기 위해 GeometryGroup Element를 사용하였다. GemoetryGroup는 FillRule 속성을 가지고 있으며 EvenOdd와 Nonzero 값을 가질 수 있다. FillRule는 Geometry가 서로 겹치는 부분을 어떻게 처리할 것인지를 결정하는 것으로써 Nonzero는 그냥 채움이고 EvenOdd는 빈공간으로 채우지 않는다.
FillRule를 EvenOdd인 경우이다.
Path를 생성하는 방법으로써 직접 직선이나 다양한 곡선을 이용해 구성하는 방법이다. 직선을 이용한 예로써 LineSegment를 사용하였다.
곡선을 이용한 예로써 ArcSegment를 이용하였다. Stroke를 완전하게 폐합하고자 한다면 PathFigure Element의 IsClosed 속성을 True로 주면 된다. 기본값은 False이다.
곡선을 이용한 또 다른 예로써 QuadraticBezierSegment를 사용하였다.
곡선을 이용한 또 다른 예로써 BezierSegment를 사용하였다.
Geometry를 이용하여 Image를 Clip하는 코드이다. 이미지를 화면에 나타내기 위해 가장 먼저 Image Element를 사용하였고 Source로 이미지 파일을 지정하였다. 이후에 Clip하기 위한 Geometry를 지정하기 위하는데, 두개 이상의 Geometry를 지정하기 위해 GeometryGroup Element를 사용하였으며 Geometry로써 단순 Geometry와 Path를 이용한 복합 Geometry를 사용하여 Clip을 위한 Geometry를 생성한다.
Path를 생성하기 위해 두개 이상의 Geometry를 사용할 경우 GeometryGroup로 묶게 되는데, 하나의 Geometry로써 PathGeometry를 사용하여, 이 PathGeometry Element 안쪽에 여러개의 Geometry 격인 PathFigure를 넣는 경우에 대한 코드이다.
Path 자체를 채움을 위한 Brush의 Pattern으로 사용하는 코드이다.
Path를 생성하는 세번째 경우로써 가장 최적화되고 함축적인 방법이다. Path Element의 Data 속성을 이용하여 좌표를 직접 하나 하나 지정한다. M은 Move, L은 Line, Z는 폐합을 의미한다. Data로써 Data=”M 10,10 A 100,50,45,1,0,200,100″와 Data=”M 10,100 C35,0 135,0 160,100 S285,200 310,100″, Data=”M 10,100 Q 200,200 300,100″, Data=”M 10,100 C 100,0 200,200 300,100″, Data=”M 10,50 V 200″, Data=”M 10,50 H 200″를 사용하여 그 결과를 확인해보기 바란다.
Path를 구상하는 Geometry에 대한 결합규칙을 지정하는 방법 중 Xor 규칙에 대한 코드와 그 결과이다. 겹치는 부분에 대해서 채움을 무시한다.
Path를 구성하는 Geometry를 하나의 Geometry로 합하는 것으로 겹합규칙을 Union을 사용하였다.
Path를 구성하는 Geometry들이 교차하는 부분만을 남기고 나머지는 무시하는 것으로 결합규칙으로써 Intersect를 사용하였다.
Path를 구성하는 Geometry들에서 첫번째에서 두번째 Geometry를 뺀 부분만을 남기는 것으로 결합규칙은 Exclude이다.
Non-Rectangle Window in WPF
오늘 작성해본 WPF에서 직사각형이 아닌 창을 나타내는 코드이다. UI 부분이므로 모든 주요 코드는 XAML에서 작성되며 드레그했을시에 창이 이동되는 이벤트 처리는 Behind Code(.CS 파일)에서 작성하였다. 먼저 XAML 코드는 아래와 같다.
창을 원하는 모양으로 만들기 위해서 반드시 설정해야할 Window의 속성은 위의 코드에서 분홍색으로 나타낸 WindowStyle, AllowTransparency, Background 속성이다. 그리고 Path Element를 이용해 원하는 모양을 그려주면 끝이다. 참으로 간단하면서도 명확하다. 실행 결과는 다음과 같다.
드레그를 하면 창이 이동을 하는데 그와 관련된 코드는 다음과 같다. 마우스의 왼쪽 버턴을 눌렸을 경우 발생하는 이벤트이다.
void eventMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { DragMove(); }