비디오 화면 크기를 조정할 때 원본 비율을 유지하고 싶을 때가 많이 있습니다.
그럴때는 아래의 방법을 사용하시면 쉽게 해결 할 수 있습니다.
DirectShow (dsshowutil.h/cpp)에서 제공하는 원본 비율유지 구현 소스입니다.
///////////////////////////////////////////////////////////////////////
// Name: LetterBoxRect
// Desc: Find the largest rectangle that fits inside rcDest and has
// the specified aspect ratio.
//
// aspectRatio: Desired aspect ratio
// rcDest: Destination rectangle (defines the bounds)
// prcResult: Pointer to a RECT struct. The method fills in the
// struct with the letterboxed rectangle.
//
///////////////////////////////////////////////////////////////////////
HRESULT LetterBoxRect(const SIZE &aspectRatio, const RECT &rcDest, RECT *prcResult)
{
if (prcResult == NULL)
{
return E_POINTER;
}
// Avoid divide by zero (even though MulDiv handles this)
if (aspectRatio.cx == 0 || aspectRatio.cy == 0)
{
return E_INVALIDARG;
}
LONG width, height;
LONG SrcWidth = aspectRatio.cx;
LONG SrcHeight = aspectRatio.cy;
LONG DestWidth = rcDest.right - rcDest.left;
LONG DestHeight = rcDest.bottom - rcDest.top;
if (MulDiv(SrcWidth, DestHeight, SrcHeight) <= DestWidth)
{
// src width / src height <= dest width / dest height
// Letterbox along the sides. ("pillarbox")
width = MulDiv(DestHeight, SrcWidth, SrcHeight);
height = DestHeight;
}
else
{
// src width / src height > dest width / dest height
// Letterbox along the top and bottom.
width = DestWidth;
height = MulDiv(DestWidth, SrcHeight, SrcWidth);
}
if (width == -1 || height == -1)
{
// MulDiv caught an overflow or divide by zero)
return E_FAIL;
}
assert(width <= DestWidth);
assert(height <= DestHeight);
// Fill in the rectangle
prcResult->left = rcDest.left + ((DestWidth - width) / 2);
prcResult->right = prcResult->left + width;
prcResult->top = rcDest.top + ((DestHeight - height) / 2);
prcResult->bottom = prcResult->top + height;
return S_OK;
}