F.R.I.D.A.Y.

Direct2D - WIC IWICBitmapScaler 본문

DEV/Direct2D

Direct2D - WIC IWICBitmapScaler

F.R.I.D.A.Y. 2021. 4. 29. 17:08
반응형

 비트맵 크기를 조절할 수 있는 IWICBitmapScaler


IWICBitmapScaler

 IBitmapSource를 기반으로 구현된 인터페이스로, 대상의 크기를 조절할 때 사용합니다.

 

사용해야하는 이유

 모든 이미지가 출력할 크기와 맞다면 모르겠지만, 많은 경우가 출력할 크기와 실제 파일의 width, height 크기가 다릅니다. 만일 원본에 크기 변형을 가하지 않은 상태로 그리게되면, 상당히 깨진 모습을 볼 수 있습니다.

 

 다음은, 휴대폰에서 낼 수 있는 최대 화소인 1억 800만 카메라로 촬영한 이미지를 윈도우 전체에 출력한 모습입니다.

 우측의 이미지는 Windows10에 내장된 사진 앱으로 파일을 열었을 때입니다. 사진 앱으로 열었을 때는 부드럽게 표현되는 이미지가 프로그램에서 열었을 때는 일부 깨진것 같은 모습으로 보입니다. 거대한 이미지를 욱여넣었기 때문에 발생하는 문제로, 이는 이미지 크기를 조절해 문제를 해결할 수 있습니다.

 

 다음은 IWICBitmapScaler로 1/10 크기[# 12000 x 9000 -> 1200 x 900]로 이미지를 줄인 후 윈도우에 그린 모습입니다.

 좀 더 부드러운 이미지가 출력된 것을 볼 수 있습니다.

 

구현

 IWICBitmapScaler 객체의 구현은 IWICImagingFactory에서 할 수 있습니다.

IWICImagingFactory* pWicFactory;
IWICBitmapScaler* pScaler;
// IWICImagingFactory 객체는 생성되어 있다고 가정한다.

if(pWicFactory){
    pWicFactory->CreateBitmapScaler(&pScaler);
}

 

비트맵 변형

 IWICBitmapScaler를 포함한 비트맵 변형을 위한 인터페이스는 Initialize라는 메서드가 포함되어 있으며, 해당 메서드를 통해 기능을 실현할 수 있습니다.

IWICBitmapFrameDecode* pFrame;
IWICBitmapScaler* pScaler;
// IWICBitmapFrameDecode에 프레임 정보가 들어있다고 가정한다.
// IWICBitmapScaler 객체가 생성되어 있다고 가정한다.

pScaler->Initialize(pFrame, scaleWidth, scaleHeight, WICBitmapInterpolationModeFant);

 첫 번째 인자는 변형을 가할 비트맵 정보이고, 두 번째와 세 번째 인자는 어느정도로 변형을 가할 것인지를 의미합니다. 만일 6000X4000 크기의 비트맵을 3000X2000으로 변형을 원하면 변형을 원하는 크기로 값을 넘겨주면 됩니다.

 

 마지막 네 번째 인자는 비트맵 변형을 어떤 방식으로 처리할 것인가에 대한 내용입니다. enum 데이터로서, 보기에서 사용한 값은 변형시에 팬트 샘플링 알고리즘[# 일정한 길이의 가로줄/세로줄의 이미지를 한 개의 픽셀로 변환하는 알고리즘. hongjjang2.tistory.com/entry/Fants-Resampling-Algorithm 이 알고리즘은 변형 폭이 두 배 이상인 경우에 쓰기 적합하다.]을 사용합니다. 더 많은 모드에 대한 설명은 아래 링크를 참고하세요.

 

WICBitmapInterpolationMode (wincodec.h) - Win32 apps

Specifies the sampling or filtering mode to use when scaling an image.

docs.microsoft.com

 

그리기

 모든 변형 인터페이스가 그렇듯이 만일 변형된 프레임으로 Direct2D에서 그리려면 IWICFormatConverter에서 포맷 변형을 해주어야 합니다.

 IWICFormatConverter의 첫 인자는 IWICBitmapSource로, 이 인터페이스를 베이스로 구현한 IWICBitmapScaler 객체를 넣어도 무방합니다.

IWICBitmapSclaer* pScaler;
IWICFormatConverter* pConverter;

pConverter->Initialize(pScaler, ...);

 

# index

728x90
반응형
Comments