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