Introduction 

WPF에서 파일로부터 불러온 이미지의 픽셀데이터에 접근하고자 할 경우 아래와 같이 CopyPixels를 통해 이미지에 포함된 픽셀 값들을 복사하는 방법을 사용합니다. CopyPixels는 이름에서도 알 수 있듯이 이미지에 있는 픽셀데이터를 복사하는데요, 이 때문에 데이터의 용도가 단순한 읽기 전용이거나 업데이트를 위한 용도일 경우에는 불필요한 메모리와 퍼포먼스를 요구하게 되므로 효율적이지 못합니다.

MSDN에서는 픽셀데이터에 접근하기 위한 또다른 방법으로 WriteableBitmap을 이야기하는데 WriteableBitmap 또한 내부적으로는 CopyPixels를 사용하기 때문에 큰 효율은 얻을 수 없습니다.)

이번시간에는 WPF내부적으로 사용되고 있는 Image Framework인 WIC(Windows Image Component)에 직접 Access하여 보다 효과적으로 픽셀데이터에 접근하는 방법에 대해 소개합니다. 아래 동영상은 WIC를 이용했을 때와 CopyPixels를 이용했을 때의 비교영상입니다.

위 테스트에서 사용된 코드는 첨부파일을 다운로드 하시면 확인 하실 수 있습니다.

Windows Image Component

앞서 말씀드린 것과 같이 WPF에서는 내부적으로 WIC를 이용해 이미지를 관리합니다. 즉 Native Code로 작성된 WIC API를 Managed Code로 Wrapping하여 제공하는건데요. 이때 Native Code에서 생성된 이미지 데이터를 Managed Code에서 무분별하게 Access할 경우 발생할 수 있는 메모리 관련 이슈들을 사전에 방지하고자 직접적인 Access를 허용하지 않고 Copy 관련 메서드만 제공하는것으로 보입니다.

※ .Net Reflector등의 툴로 BitmapSource객체를 열어보시면 아래와같이 내부적으로 WIC 이미지를 가지고 있는것을 확인 하실 수 있습니다.

_wicSource라는 이름으로 WIC객체가 저장되어 있는것을 확인하실 수 있습니다. wicSource는 Internal로 정의되어있기 때문에 Reflection을 통해 WIC객체 포인터에 Access하고 WIC API를 이용해 Native Code상에서 생성된 이미지 데이터에 접근하시면됩니다.

WIC에 대한 자세한 내용은 여기(http://msdn.microsoft.com/ko-kr/library/windows/desktop/ee719654.aspx)서 확인 할 수 있습니다.

Create WICBitmapBuffer

WIC를 이용해 픽셀 데이터를 접근하기 위해 필요한 API들과 Native객체 생성과 파괴를 관리 할 수 있도록 임의의 WICBitmapBuffer를 아래와 같이 사용하면 더 쉽게 사용할 수 있습니다.

위 코드를 사용할 때에는 아래와 같이 사용합니다. WICBitmapBuffer.Create 메서드에 BitmapSource객체를 넣고 Buffer에 접근하시면 됩니다.

이상으로 이번 포스팅을 마치며 영상에서 사용된 전체 소스코드는 아래에서 다운로드 받으시면됩니다. 기타 질문이나 문의사항은 댓글이나 이메일 주시면 답변드리도록 하겠습니다. 감사합니다.

WIT.WPF.BitmapExtensionExample.zip

 

신고

Introduction

WPF를 이용해 Application을 개발 할 때 기본 Window모양이 아닌 임의의 디자인의 Window로 구현해야 하는 경우가 있습니다. 이때 아래 그림과 같이 WindowStyle 속성과 AllowsTransparency 속성을 이용해 기본 Frame을 나타나지 않도록 구현 할 수 있는데요.

WindowStyle을 None으로 설정할 경우 기본 제목 표시줄을 사라지지만 윈도우의 테두리에 크기를 변경할 때 사용하는 테두리가 남아 있는데요. 이를 제거하기 위해서 AllowsTransparency 속성을 True 지정하면 이 테두리가 사라지게 됩니다. 그런데, 한가지 문제점은 AllowsTransparency 속성이 True일 경우에는 기본적으로 마우스를 이용해 크기조절이 불가능하기 때문에 크기조절 부분을 직접 구현해줘야 하는 단점이 있습니다.

이번시간에는 위와 같은 상황에서 간단하게 크기를 조절하거나 창을 움직일 수 있도록 하는 WindowResizer를 소개합니다. 개인적으로 만들어 사용하던 코드인데 마침 정리 할 기회가 되어 공유합니다. 아래 동영상은 샘플로 사용된 코드의 시연 영상입니다.

How to use WindowResizer

WindowResizer를 사용하기 위해서는 아래와 같이 XAML에 WindowResizer의 네임스페이스를 추가하고, 리사이즈 영역으로 사용할 객체에 WindowResizer.Direction 속성을 Left, Right, Top, TopLeft, TopRight, Bottom, BottomLeft, BottomRight, Drag중 하나로 지정하면 됩니다.


그리고 C#코드에서 WindowResizer를 적용하고자 할경우 아래와 같이 사용하실 수 있습니다.

이상이며  아래는 WindowResizer의 샘플 프로젝트와 전체 소스코드파일입니다. 기타 궁금하신점이나 문의사항은 이메일이나 댓글로 남겨주시면 답변드리도록 하겠습니다.

WIT.WPF.Samples.WindowResizerExample.zip

신고

Introduction

이번시간에는 정규표현식을 이용해 String Format이 적용된 텍스트에서 값을 추출하는 방법에 대해 소개합니다. 아래는 이번시간에 구현하게될 내용의 스크린캡쳐 화면 입니다.

About StringFormat

.Net에서 StringFormat은 입력된 텍스트를 일정한 형식(Format)에 맞춰 텍스트를 변환해주는것을 의미하며 String.Format이나 Console.WriteLine등에서 사용합니다. Composite formatting이라고도 부르는 StringFormat은 일반적으로 "고정문자열"과 "서식"으로 이루어지는데  아래 코드를 보면, 고정 텍스트는 "Name = " 과 ", "Hours = "입니다.

그리고 서식은 {}(중괄호)로 묶여 있는 {0}과 {1:hh}부분입니다.

서식 부분은 "{index[,alignment][:formatString]}"와 같이 구성되는데 중괄호와 index만 필수 항목이고 alignment속성이나 formatString부분은 옵션입니다. String Format과 관련된 자세한 내용은 MSDN에서 확인 하실 수 있습니다. (http://msdn.microsoft.com/ko-kr/library/txafckwd.aspx)

Reverse String Format Using Regex

다시 본론으로 돌아와서 StringFormat이 적용된 텍스트에서 원래 값을 추출하기 위해서는 위에서 언급한 StringFormat에 사용된 서식부분을 추출하는게 우선 인데요. 아래 코드와 같이 정규표현식 "\{(.*?)\}"를 StringFormat으로부터 서식 부분을 찾고 이부분에 어떤 텍스트라도 찾을 수 있 수 있도록 "(.*?)"로 변환 합니다.

 
이렇게 생성한 정규표현식을 StringFormat이 적용된 텍스트에 적용하면 입력 텍스트만 추출 할 수 있습니다. 아래는 이번시간의 전체 소스코드입니다.

이상이며 이외 궁금하신점이나 문의사항은 댓글이나 이메일로 주시면 답변드리도록 하겠습니다.

신고

Introduction

어플리케이션을 개발할때 간혹 파일을 암호화 해야 하는 경우가 있습니다. 이번시간에는 파일을 암호화하는 방법중에서 가장 널리 이용되고 있는 RSA와 AES(DES)를 이용해 파일을 암호화 하고 복호화 하는 방법에 대해 소개합니다. 아래는 이번시간에 구현하게될 샘플 동영상입니다.

위 동영상의 시연 순서를 설명드리면 아래와 같습니다.

1. Generate Key버튼을 이용해 RSA키를 생성한다. (입력된 파일 명으로 개인키와 공개키가 생성)
2. Encrypt File버튼을 이용해 선택한 파일을 암호화한다. (선택한 파일과 동일한 폴더에 ".Encrypt" 확장자의 암호화된 파일이 생성)
3. Decrypt File버튼을 이용해 선택한 파일을 복호화한다. (선택한 파일과 동일한 폴더에 ".Decrypt" 확장자의 복호화된 파일이 생성)
4. ".Decrypt" 확장자의 파일을 원래 확장자로 변경하여 복호화가 정상적으로 이루어 졌는지 확인한다.

※ RSA의 경우 개인키로는 암호화/복호화가 모두 가능하지만 공개키로는 암호화만 가능합니다.

Encryption & Decryption Principles

이번시간에 구현한 샘플 프로그램의 동작원리는 아래와 같습니다.

먼저 암호화를 위해서 RSA로 생성한 개인키/공개키를 이용해 AES 또는 DES 대칭키를 암호화 합니다. 그리고 RSA로 암호화된 대칭키와 초기화 벡터를 암호화 결과 파일이 저장될 공간의 앞부분에 크기와 함께 저장합니다. 그리고 대칭키를 이용해 데이터를 암호화 를 진행합니다.

복호화는 이와 반대로 수행하면 됩니다. 암호화된 파일의 앞부분에서 암호화된 대칭키를 추출하고, 이를 RSA 개인키를 이용해 복호화 한다음 복호화된 대칭키를 이용해 암호화된 데이터를 복호화 합니다.

Create EncryptUtil


위에서 말씀드린 과정을 수행하기 위해서 위와 같은 기능을 가진 EncryptUtil클래스를 생성했습니다. EncryptFile 메서드와 DecryptFile 메서드는 SymmetricAlgorithm 타입을 받는 제너릭 메서드로 구현되어 있으며 사용하실 때에는 아래와 같이 AesCryptoServiceProvider 혹은 DESCryptoServiceProvider를 넘겨서 사용하시면됩니다.

 
아래는 이번시간에 사용한 샘플 코드의 전체 소스코드입니다. 포스팅과 관련해 궁금하신 점이나 문의사항은 댓글이나 메일로 주시면 답변드리겠습니다. 감사합니다.

WIT.EncryptionDecryption.zip

 

신고

Introduction

일반적으로 Image Viewer 등과 같이 화면에 출력해야할 내용이 화면크기보다 클 경우 ScrollViewer를 이용해 내용을 스크롤할 수 있도록 구현을 하는데요, 이번시간에는 화면을 스크롤하기 위해서 스크롤바를 조작하지 않고 간단한 마우스조작으로 컨텐츠를 직접 드래그하는 방식으로 View를 조절하고 확대 축소할 수 있는 기능을 구현해보았습니다. 아래는 이번시간에 구현한 결과물 영상입니다.

Create ZoomAndPanning Behavior

Zoom 또는 Panning의 경우 자주 사용될 수 있는 기능이기 때문에 재사용을 용이하게 하기 위해서 Behavior의 형태로 작성했습니다. ZoomAndPanning Behavior의 기본적인 구성은 와래와 같습니다.

ScrollViewer의 기본적인 마우스 이벤트와 ScrollChanged이벤트를 수신하고 각 이벤트마다 적적할 처리를 진행 해줬습니다. 그리고 추가적으로 최대 확대배율이나 최소 확대배율, Zoom And Panning 단축키등을 통해 다양한 조작환경을 제공 할 수 있도록 구현됬습니다.

소스코드자체가 어려운 내용들은 아니기 때문에 이번시간에는 별도의 코드 설명은 생략하겠습니다. 아래는 이번시간에 사용한 전체소스코드 파일이며 VisualStudio 2010에서 작업되었습니다. 기타 질문이나 문의사항은 이메일이나 댓글남겨주시면 답변드리겠습니다. 감사합니다.

WIT.WPF.Sample.ZoomAndPanningBehaviorExample.zip

신고