안녕하세요. 김대욱입니다. 새롭게 선보인 VisualStudio 2010과 WPF 4.0에 대한 내용을 다룬 WebCast가 새로 등록되었습니다 ^^
위 그림을 클릭하시거나, 아래 주소를 통해 확인하실 수 있습니다.
세션보러가기 : http://www.techdays.co.kr/visualstudio2010/
WPF 4.0에서 새로 추가된 기능들에 대해 소개하고, WPF4.0을 이용한 Windows7용 Application개발과 관련된 데모가 포함되어있습니다 ^^ 많은관심 부탁드려요!
안녕하세요. 김대욱입니다. 이번시간에 소개해 드릴 내용은 임의로 제작한 Attribute를 UI에 Binding 하기 위한 MarkupExtension에 대해 소개해 드리겠습니다. 이 내용은 데브피아 WPF&Silverlight마을에서 이광현 (dololas)님께서 질문해주신 내용입니다. 간단하게 이번시간에 하고자 하는 내용을 그림으로 표현 하면 아래와 같습니다.
먼저 위 그림과 같이 Header부분에 제목, 감독, 출연배우라고 출력만 하면 되는 상황이라면 아래와 같이 직접 명시해줄 수 있을텐데요, 질문자 님께서 말씀 하신 내용은 명시적으로 Header값을 입력하지 않고, 지정한 Attribute에 따라 Header의 출력 내용을 결정 하고자 하셨으므로 이에 따른 해결 방법에 대해 알아보도록 하겠습니다.
이번 예제에 사용되는 Class와 Attribute의 구조는 다음과 같습니다.
일단 위와 같은 상황에서 가장먼저 떠오르는게 DataBinding이 지만, DataBinding은 Property와 Property간의 연결을 제공하기 때문에 Attribute와는 함께 사용하실 수 없습니다. 따라서 Attribute 값을 반환 하는 MarkupExtension을 구현하여 해결해야 합니다. 아래는 MarkupExtension 구현 부분 소스코드입니다.
MarkupExtension 파라미터로 입력받은 Type과 MemberPath정보를 기반으로, CustomAttribute의 값을 가져옵니다. 간단하죠? 실제 사용할때에는 아래와 같이 사용하시면 되겠습니다.
이상으로 이번시간 내용을 마치며, 기타 질문은 리플이나 이메일로 해주시면 답변 드리도록 하겠습니다. 아래는 이번시간에 사용된 전체소스코드입니다.
안녕하세요. 김대욱입니다. 이번시간에 소개해 드릴내용은 WPF에서 사용할 수 있는 AngleGradientBrush를 제작하는 방법이 되겠습니다. AngleGradient란 아래 그림을 보시면 쉽게 이해 하실 수 있을텐데요, WPF에서는 LinearGradient, RadialGradient만을 제공하는걸 하기때문에 (ReflectedGradient와 Diamond Gradient는 LinearGradient를 이용해 구현할 수 있습니다.)
Angle Gradient와 같은효과 나타내고자 한다면 직접 구현해서 사용해야 합니다.
그런데, 막상 구현을 해서 사용하려고 보면 WPF에서 Custom Brush 제작을 지원하고 있지 않아 직접 구현하는것도 어려워보입니다. 해외 포럼이나 블로거들을 보면 많은 분들께서 Angle Gradient와 관련된 내용에 대해 궁금해 하시는걸 확인할 수 있었는데요. 대부분 Angle Gradient를 Photoshop등에서 미리 그려서 Image File로 가지고 있다가, ImageBrush를 사용하는 방법을 사용한다고 합니다. 하지만, 이런 방법의 경우 Runtime 중에 Gradient Stop을 지정할 수 자유도가 많이 떨어지게 됩니다.
위동영상을 보시면 Runtime중에 자유롭게 Gradient Stop을 지정할 수 있고, Gradient Size, Gradient Detial, CenterPoint등을 의 크기를 지정할 수 있습니다. 원리는 아주 간단합니다. Property를 통해 GradientStop 정보와 Size, Detail, CenterPoint 등의 정보를 입력받고 이를 기반으로 직접 Gradient Image를 생성합니다. 그리고 MarkupExtension의 ProvideValue에 생성한 Image를 사용하는 ImageBrush를 반환 하는 방법을 사용합니다.
그럼 이제 중요한건 Angle Gradient Image를 어떻게 생성하는가가 되겠습니다. 저같은 경우 아래와 그림과 같은 방법을 이용하여 Gradient Color를 계산하고 활용했습니다. WPF에서는 이미 LinearGradient를 제공하기 때문에 Gradient Stop을 입력하면 자연스러운 Gradient 색상을 추출 할 수 있고, 회전 각에 따라 추출된 색상정보를 매핑하면 아래와 같은 Angle Gradient Image를 생성 할 수 있습니다.
아래 코드는 GradientStopCollection에 저장된 GradientStop정보를 가지고 Gradient Color Code를 추출 하는 내용과 ColorCode를 이용해 AngleGradient Image를 생성하는 코드입니다. 코드 자체는 특별하게 어려운 부분은 없으니 한줄한줄 천천히 살펴보시면 이해하시는데에는 무리가 없을것같습니다.
그리고 실제 사용할 때에는 아래와 같이 사용할 수 있습니다.
이번시간에 중요한 내용은 MarkupExtension을 이용해 XAML을 확장하는 방법과 그리고 Gradient Image를 생성하는 부분이 되겠습니다. 그리고 아래는 이번시간에 사용한 전체 소스코드이며, 기타 질문이나 문의는 리플이나, 이메일로 주시면 되겠습니다!
안녕하세요. 김대욱입니다. 최근들어 터치스크린을 이용한 프로젝트를 자주 진행하다보니 이번 포스팅은 터치스크린을 이용하는 시스템에서 유용하게 사용될 수 있는 내용이 되겠습니다. 이번시간에 소개해 드릴 내용은 터치스크린을 사용하는 어플리케이션에서 TextBox등의 Control에 Focus 되었을때 자동으로 Screen Keyboard Application을 실행하는 예제입니다. 동영상을 보시면 쉽게 이해하실수 있습니다.
위 동영상에서는 WIndows에서 기본적으로 제공하는 OnScreenKeyboard를 사용했지만, 이번시간에 소개해 드릴 내용을 응용하면 직접 개발한 Keyboard Application을 사용하실 수도 있습니다. 간단하게 원리를 말씀드리자면 입력가능한 컨트롤 즉, TextBox나 PasswordBox에 Focus 되었을때 미리 지정해놓은 Keyboard Application을 실행하고 Focus를 잃었을때 Keyboard Application을 닫는 원리가 되겠습니다.
컨트롤 하나하나 일일이 Focus이벤트 코드를 추가하는 방법을 사용할수도 있겠지만, 이번시간에 소개해 드릴방법은 Attached DependencyProperty를 사용하여 간단하게 Screen Keyboard를 지원하도록 구현했습니다. 사용할때에는 아래와 같이 사용할 수 있습니다.
아래는 Attached DependencyProperty를 구현한 소스코드입니다.
동작원리는 위에서 설명드린것과 동일하며 Attached Dependency Property를 이해하고 있다면, 어렵지 않게 이해하실수 있을것 같습니다 ^^ 이상으로 이번 포스팅을 마치며 질문의나 문의 사항은 언제든지 연락주시기 바랍니다 ^^ 감사합니다.
안녕하세요. 김대욱입니다. 포스팅제공 기능만들어 놓은지 일주일정도가 지났습니다. 생각보다 많은 분들이 소재를 제공해주고 계서서 감사하다는 말씀 드립니다 꾸벅 (__) 얼마전에 김진필님께서 포스팅 제공기능을 통해 MediaPlayer를 사용하는 예제에 대해 요청해주셨는데요. 이를 반영하여~~!!! 이번시간에 소개해 드릴내용은 WPF에서 제공되는 MediaPlayer를 이용한 영상 Thumbnail이미지 추출 방법입니다. 아래는 구현완료시 결과물 스크린샷입니다.
샘플에 사용된 영상은 헤일로 광고 영상같은데.. 스타크레프트 말고는 아는게임이 없어서 확실한지는 잘모르겠습니다.. ^^;;
먼저 코드를 살펴보겠습니다.
코드가 엄청 길어보이는데, 주석이 절반이므로 너무 걱정하실 필요는 없습니다. 아마 WPF를 사용해서 동영상 플레이어를 제작하고 계시는 분들이나 혹은 예정이신 분들에게는 유용한 정보가 되지 않을가 싶습니다.
주석으로 코드에대한 설명을 적어놨지만, 간단하게 내용을 요약해보자면, MediaPlayer를 생성하고 Thumbnail추출을 원하는 영상을 Open한뒤 Position을 변경해가며 RenderTargetBitmap을 활용해 MediaPlayer의 화면을 캡쳐합니다. 참~~ 쉽줘잉~
아래는 이번시간에 사용한 소스코드입니다. 영상을 Open하시고, Extract Thumbnail버튼을 클릭하시면 자동으로 추출됩니다. 기타 질문은 이메일 또는 리플로 남겨주세요~~
안녕하세요. 김대욱입니다. 자기전에 포스팅 하나 하고자야겠다 싶어 새벽 포스팅 시작합니다. ㅎㅎ
이번시간에 소개해 드릴 내용은 WPF를 이용해 아래와 같이 문자열로 이루어진 이미지를 만드는 방법입니다. 제목은 조금 거창하게 ASCII Art라고 소개했지만 일정 공백을 두고 픽셀 정보를 가져와 이를 문자열로 바꾸기만하면되는.. 매우 간단한 예제가 되겠습니다...(낚시 제목.. ㅈㅅ) 아래 사진속 고양이는 저희집에서 저와 함께 살고 있는 쿠루 입니다 +_+
위 그림에서 보시다 시피 이미지를 입력하면 해당이미지를 문자로만 이루어진 이미지로 변환 하기 때문에 폰트 크기가 작으면 작을 수록 원본이미지와 유사한 이미지로 나타나는 것을 확인 하실 수 있습니다. 구현 방법 소개에 앞서 동영상을 보면서 어떻게 동작하는지 한번 생각해보시기 바랍니다~!! 동영상 캡쳐할때 화질이 좋지 못해서 색상이 이상하게 표현되네요 ㅠㅠ ㅋ 화질좋고 빠른 동영상 캡쳐 툴 있으면 추천해주세요~!~!
사실 이번시간에서의 중요한 대부분의 코드는 XAML보다는 C#코드로 되어있습니다. 설명은 주석에 적어놨으니 참고하시길 바라며 아래는 이미지의 경로를 입력하면 임의의 문자열과 적합한 색상값을 갖는 객체를 추출 하는 작업에 대한 코드입니다.
코드자체가 어렵진 않기때문에 이해하시는 데에는 큰 무리가 없을것으로 생각되며, 제가 이번시간에 ASCII ART예제를 준비하면서 말씀드리고 싶은 중요한 내용은 BmpBitmapEncoder를 이용해서 간단하게 PixelData를 가져올수 있다~!~! 라는것입니다. 예전에 System.Drawing.Bitmap객체를 활용해서 Pixel Data를 접근 방법에 대해 소개해 드린적이있지만, Bitmap Class는 WPF에서 기본적으로 사용하는 Class가 아니기때문에 Reference를 추가하는 등에 작업이 필요합니다, 하지만BmpBitmapEncoder와 MemoryStream을 사용하면 위 작업을 하지 않아도 PixelData에 접근이 가능하기 때문에 이번 예제와 같은 내용을 개발하실 때 상당히 유용할것 같습니다. (단, 위 방법을 사용하실 경우 수정시 원본이미지에 반영 되지는 않습니다..)
나머지 위 코드를 호출하는 부분등은 아래 첨부한 소스코드를 보시면 확인하실수 있습니다. 기타 질문이나 문의 요청사항은 이메일이나 리플 오른쪽 포스팅 소제 제공을 통해 문의 하시면 되겠습니다 ^^
PS. 제작할때 폰트를 굴림체, 돋움체, 궁서체 등 모든 문자의 크기가 동일한 폰트를 활용하면 굳~~~~ 입니다.
안녕하세요. 김대욱입니다. 방금전에 세미나를 끝마치고 돌아왔습니다 ..
생각보다 많은 분들께서 참석을 해주셔서 조금 당황하긴 했지만 다행히 특별한 사고 없이 끝난것 같아 다행이네요 ^^;
사전준비가 철저하지 못해 다소 미흡했던 부분들이 있었다면 너그럽게 이해 해주셨으면 감사하겠습니다.(__) 꾸벅.
세미나에 참석하지 않으셨거나, 혹은 참석하셨지만, 샘플 소스 CD를 받지 못하신 분들을 위해 샘플 소스 CD이미지 (ISO로 되어있습니다.)를 올려드립니다. 블로그에 등록된 내용이거나 기존 내용에서 좀더 사용하기 쉽도록 변경한 코드들이 포함되어 있습니다.
용량이 생각보다 큰 관계로 3개로 분할압축하여 업로드 했습니다. 압축은 ALZ 포멧으로 압축되어 있으며 알집등으로 압축을 푸시면 ISO이미지를 확인하실 수 있습니다. 이외 세미나때 질문하지 못했던 부분이나, 기타 다른 질문은 이메일, 방명록,리플 등등등 다양한 방법으로 연락주시면 답변드리도록 하겠습니다.
안녕하세요. 이번시간에는 WPF를 사용해서 간단하게 PhotoMosaic을 구현 해보도록 하겠습니다. 아래는 시연 동영상이며, 화면이 작아 잘안 보이시는 분들을 위해 설명을 드리자면 모자이크를 만들고자 하는 원본 이미지를 불러오고 모자이크에 사용하고자 하는 이미지의 검색어를 입력한뒤 Make버튼을 누르게 되면 Flickr에서 검색어에 해당하는 이미지를 불러와 원본이미지와 함성해주는 내용입니다.
결과를 자세히 살펴보면 다음과 같습니다. (허락 없이 올린 여자친구 사진인데.. 혼나면 어떡하지.............. -_-)
사진을 확대해보면 여러장의 사진이 모여 하나의 사진을 이루고 있는 모습을 확인 하실 수 있습니다.. PhotoMosaic을 구현하는데 있어 색상정보를 기반으로 하는 방법등 여러가지 방법이 있지만, 이번시간에 구현한 방법은 가장 간단하게 구현 할 수 있는 Tile Image의 투명도를 조절하여 구현하는 방법입니다.
아래는 PhotoMosaic을 구현하는데 사용한 소스코드이며 코드에 대한 설명은 주석으로 달아놓았습니다!!
간단하게 요약하자면 DrawingImage를 사용해 원본이미지를 가장 먼저 그리고 Flickr에서 검색된 이미지들을 랜덤하게 그려주는 과정을 수행합니다. 이때 Flickr에서 검색된 Tile Image의 Opacity를 낮춰 배경이 비치도록 만들어 마치 여러장의 이미지들이 하나의 이미지를 이루는것과 같은 효과를 냅니다.
위 코드에서 가장 중요한 부분은 Flickr에서 이미지를 불러올때 CacheOption을 사용하여 이미지가 재사용될때 빠르게 응답할 수 있도록 하는 부분에 있습니다. (CacheOption을 사용하지 않으면 저장할때 엄청난 시간이 소요될 수 있습니다..)
실제 사용하실 때에는 아래와 같이 간단히 객체를 생성한뒤 Source Image를 지정하고 Tile의 Scale을 지정한 뒤 Make함수를 호출하시면 되겠습니다.
아래는 이번시간에 사용된 전체소스코드이며 기타 질문이나 요청 문의 등은 이메일 또는 리플로 남겨주시면 답변드리겠습니다 ^^
안녕하세요. 지구온난화로 인해 어쩌고저쩌고 해서 날씨가 개떡같음을 한탄하는 1人 김대욱입니다. -_-;; ㅋㅋ
최근들어 WPF를 이용해 CubeUI를 구현하는 방법에 대해 문의하시는 분들이 많아 이번시간에는 Cube UI를 WPF의 ListBox에 적용하여 이를 구현는 방법에 대해 소개해 드리고자 합니다..!! 아래는 구현 완료 동영상 입니다.
동영상만 봐서는 저게 뭐에다가 쓰이는 물건인지.. 감이 안잡히시죠?? (제목을 보셨다면 이해 하셨을수도.. ㅎㅎ) 이번시간에 구현할 내용은 WPF3D를 이용해 기존의 Listbox를 Cube모양으로 만들어 활용하는 방법에 대해 소개해 드리겠습니다. 먼저 구조에대해 설명을 드리겠습니다. (소스코드를 다운로드 받으셔서 확인해 가시면서 보시면 이해가 빠를것 같습니다!)
프로젝트를 열어보면 위 샘플에 사용된 이미지 몇장과 Cube3D.xaml, CubeListBox.xaml이 있습니다.
Cube3D.xaml은 Cube UI이기 때문에 Cube 모양을 정의 하는 Geometry가 포함된 ModelVisual3D객체 입니다. Cube3D에는 Front, Back, Left, Right, Top, Bottom이라 이름의 Property가 존재하는데요, 이는 Cube의 각각 면에 해당하는 합니다.
그리고 OffsetX, OffsetY, OffsetZ ... RotationZ 등은 제가 WPF를 이용해서 3D를 구현할때 자주사용하는 코드로 간단하게 Offset, Scale, Rotation을 적용하기 위한 코드입니다. 이부분은 다음에 더 자세히 다루도록 하겠습니다.
그다음 CubeListBox입니다. CubeListBox는 위에서 말씀드린 Cube3D를 템플릿에 활용하여 구현된 ListBox입니다. Template부분 코드를 보면 아래와 같습니다.
Viewport3D를 이용해 WPF3D를 사용하기 위한 Viewport를 생성하고 적당한 카메라와 조명의 위치를 잡은 뒤 위에서 말씀드렸던Cube3D객체를 추가합니다. 그리고 각면에 SelectedItem, PrevItem, NextItem등을 Binding하게되는데요.
여기서 Front에 SelectedItem을 Left에 PrevItem을, Right에 NextItem을 Binding하는 이유는 잠시후에 설명하도록 하겠습니다.
(SelectedItem은 사용자가 현재 ListBox에서 선택한 객체를 보여주고, PrevItem는 이전 NextItem은 다음 객체를 의미합니다.)
PrevItem과 NextItem은 Listbox에 기본적으로 정의된 Property가 아니기 때문에 새로 Dependency Property로 정의 하고, SelectedIndex가 변경되었을때 아래와 같은 내용으로 PrevItem과, NextItem에 값을 할당 해줍니다.
ListBox에 추가된 객체의 갯수보다 Nextndex가 클경우 Index를 0으로 설정하여 순환구조로 작성했으며 PrevIndex가 0보다 작을경우 마지막 항목의 Index를 지정하여 마찬가지로 순환구조를 가지도록 했습니다.
이렇게 하면 Cube상에 현재 선택된 객체는 Front에 다음 객체는 Right에 이전객체는 Left에 위치하게 됩니다. 이제 마우스 조작을 통해 큐브를 회전시키는 부분을 구현할 건데요...해당코드는 아래와 같습니다.
Cube를 회전 한다고해서 실제 ListBox의 SelectedIndex가 변경되는것이 아니기 때문에 회전 Animation이 완료되면 회전 방향에 따라 Index를 증가 또는 감소 시켜줍니다.
이렇게하면 Front에는 현재 선택된 객체가, Left에는 이전, Right에는 다음 객체가 보여지게 되는데요. 회전을 하게되면 Cube자체의 Front, Left, Right 면의 위치가 변하게 되어 뜻하지 않은 결과를 발생시킵니다. 이를 위해 Cube의 회전이 모두 끝나면 Animation을 제거하여 큐브가 회전하지 않은 상태가 되도록 합니다.
이렇게 구현된 CubeListBox는 아래와 같이 일반적인 ListBox와 같은 방식으로 사용하실 수 있습니다.
이상으로 이번 포스팅을 마치며 기타 질문이나 문의 포스팅 요청은 이메일이나 리플로 남겨제요 ^^
아래는 이번 시간에 작업한 내용의 전체 소스코드입니다.