Introduction
WPF Application을 개발하다보면 현재 화면에 출력되고 있는 Visual객체나 임의로 생성한 Visual 객체를 Image로 변환 해야하는 경우가 있습니다. 이번 강좌에서는 RenderTargetBitmap을 이용해 Visual 객체를 Image로 변환하는 방법에 대해 소개합니다.
What is RenderTargetBitmap?
RenderTargetBitmap은 WPF상의 Visual객체를 Bimap으로 변환 해주는 클래스로, 제공되는 Render메서드를 통해 Visual 객체를 Bitmap으로 변환 할 수 있습니다. Render메서드를 호출하게 되면 입력한 Visual의 Measure와 Arrange를 수행한 결과를 바탕으로 생성된 Bitmap영역에 Visual을 렌더링 하게됩니다. RenderTargetBitmap은 생성자로 생성할 Bitmap의 Width, Height, DpiX, DpiY, PixelFormat을 파라미터로 전달받으며, 기본적인 사용법은 아래와 같습니다. 아래 코드는 파라미터로 전달받은 Visual객체를 BitmapSource로 변환 하는 함수입니다.
Some Problems in RenderTargetBitmap
Flexible Size
RenderTargetBitmap은 입력받은 Visual객체를 Bitmap형식으로 변환되기 때문에 Bitmap으로 저장될때의 크기가 정확하게 지정되어야 합니다. 위 코드에서는 크기를 지정하기 위해 객체의 Width와 Height속성을 이용했는데, WPF의 Layout 구조상 렌더링 타임에 크기가 측정되는경우 Width, Height속성이 실제 렌더링 결과와 차이가 있을 수 있습니다. 이를 보안하기 위해 객체의 렌더링시 크기를 가져오는 ActualWidth, ActualHeight속성을 이용 할 수 있습니다.Non-Parent / Pre-Measure
위에서 언급한 ActualWidth, ActualHeight는 VisualTree에서 수행하는 크기 측정과정을 통해 측정된 결과를 반환 하기 때문에, 부모가 없는 Visual이거나 한번도 측정을 수행하지 않은 경우에는 항상 0을 반환하게 됩니다. 크기가 0일경우 렌더링시 아무것도 내용도 출력되지 않기 때문에 원하는 결과를 얻을 수 없습니다. 이경우 직접 측정을 수행하도록 Arrange 메서드를 호출하는 방법으로 해결 할 수 있습니다.Transform Size
ActualWidth나 ActualHeight는 Transform을 고려하지 않은 실제 Visual의 크기를 반환 합니다. 때문에 Transform이 적용된 객체의 경우 원하는 결과와 다르게 동작하게 됩니다. 이 경우 Transform객체의 TransformBounds메서드를 통해 Transform이 적용된 영역을 계산 할 수 있습니다. 아래 코드는 위에서 언급한 몇가지 문제점을 개선한 코드입니다.위 코드를 사용할 때는 다음과 같이 이용할 수 있습니다.