안녕하세요 :) 김대욱입니다. 이번에도 포스팅이 늦어 죄송하다는 말로 시작합니다.. ㅠ
이번시간에는 WPF에서 제공되는 기본 Image Control보다 훨씬 깔끔하게 Image를 출력해주는 Fixed Image Control을 구현하는 방법에 대해 소개합니다. 아래는 구현 결과의 예로, 똑같은 내용의 텍스트가 기록된 이미지를 WPF 기본 Image Control을 사용하여 출력했을 때와 이번시간 구현하게될 FixedImage Control을 사용하여 출력했을때를 비교한 결과입니다.
이러한 문제는 WPF의 장점이라면 장점, 단점이라면 단점이 될 수 도 있는 WPF만의 독립적인 좌표계 덕분에(?) 객체가 흐릿하게 보여지는 것입니다. 이전에 SnapsToDevicePixels Property를 사용하여 위와 유사한 문제를 해결하는 방법에 대해 소개해 드린바 있습니다만,
SnapsToDevicePixels를 사용하여 위 문제를 해결하기 위해서는 Layout이 변경될때마다 VisualXSnappingGuidelines와 VisualYSnappingGuidelines를 직접 지정 해줘야 하는 번거러운 작업이 따르기 때문에 그닥 좋지 방법이라 할수는 없어 보입니다. (레이아웃이 죽어도 변경될일이 없고, 사용하는 장치는 항상 동일하다 하신다면 이방법을 사용하시는것도 나쁘진 않겟네요 :)
그렇다면 Fixed Image는 어떤 방식을 사용했을가요?
뭔가 엄청난 방법이 숨겨져 있지 않을가... 하셨겠지만 사실은 간단합니다. WPF에서 객체를 출력할 때 장치의 좌표에 맞춰 출력하도록 한건데요. 일종의 trade off라 할수 있겠습니다. 우리가 일반적으로 사용하는 데스크탑에서는 기본 좌표가 Pixel단위다 보니 소수점 표현이 불가능하죠. 하지만 벡터 기반의 WPF에서는 레이아웃 계산시 소수점을 사용하기 때문에 픽셀이 가운데 걸쳐 버리게되는 현상이 생깁니다. (이 내용은 이전 포스팅이나 MSDN을 참고해주세요^^ )
따라서 WPF가 객체를 (100.123, 100.678)의 위치에 출력하려고 할때 소수점을 제외한 위치인 (100, 100) 에 출력하도록 하면되겠습니다. 아래는 위에서 FixedImageControl의 소스코드입니다. 이번엔 예시를 보여드리기 위해 Image Control에 적용했지만, 위와 같은 방법을 적용한다면 Image Control이외에 다른 Control에도 적용할 수 있습니다. 코드에 대한 설명을 주석을 참고해주세요.
위 코드중에서 가장 중요한 부분은 객체가 출력될때의 좌표가 소수점에 해당되는지, 소수점이라면 정수로 변환하기 위해 어느정도 이동을 해야하는지를 계산하는 GetOffset부분과 Rendering 시에 TranslateTransform을 Push해주는 부분이 가장중요하다고 생각되니 이부분을 중심으로 살펴보시면 이해하시는데 큰 어려움은 없으실것 같습니다.
그럼 오늘 포스팅은 여기까지로 하고, 이번 포스팅에 대한 질문이나 기타 문의는 이메일 또는 댓글로 남겨주시면 답변해드리도록하겠습니다. 그럼 좋은밤되세요~ 뿅~ :)
아래 첨부파일은 FixedImageControl의 전체소스코드와 샘플 프로젝트파일입니다.

FixedImage.zip
