保持纵横比 [英] Maintaining Aspect Ratio

查看:120
本文介绍了保持纵横比的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

1920 x 1080图像的宽高比为16:9。我可以把图像放到D3DImage中没问题。我使用它作为Canvas对象的背景。这也很有效。为了在用户改变窗口大小来调整画布大小时进行适当的缩放我在ViewBox中有Canvas。



我的问题是画布是否已设置大小为16:9的宽高比,比如说640 x 360,当ViewBox调整画布大小时,会保持宽高比吗?



这与我的关系其他问题 画布中D3DImage的公共坐标 [ ^ ]



@BillWoodruff,道歉,这是一个WPF / DirectX问题。



@Sergey,你说的有意义,但ViewBox似乎会照顾这个。



真的很奇怪。当我得到Height / Width / PixelHeight或PixelWidth时,无论在屏幕上看到什么,它都会报告1920 x 1080,但只要我以16:9比例的Cavas大小开始,它总是看起来正确。此外,Canvas永远不会得到一个事件,表明它已经调整大小但ViewBox没有。

谢谢,

Doug

解决方案

您必须在代码中支持它。采用边界矩形并考虑两种不同的情况:如果它的纵横比大于或小于目标值。在一种情况下,您可以在左侧和右侧创建两个垂直未使用的波段,在第二种情况下 - 在顶部和底部创建两个水平波段。边界矩形和目标矩形的纵横比将是其中一种情况的特例;这是你的选择;在这种情况下,图像将占据边界矩形的整个区域。



-SA


< blockquote>这是我用C ++编写的宽高比函数,你可以轻松地将它转换成我想象的。



内联CRect GetTargetRect(CRect rTarget,CSize szSource,
unsigned int uiAlign = DT_CENTER | DT_VCENTER)
{
// 保持纵横比
float fLeft =( float )rTarget.left;
float fTop =( float )rTarget.top;
float fWidth =( float )rTarget.Width();
float fHeight =( float )rTarget.Height();
float fPercentCy =((fHeight / szSource.cy)* 100 );
float fPercentCx =((fWidth / szSource.cx)* 100 );
float fNewWidth = 0 ;
float fNewHeight = 0 ;

// 查看是否拉伸或收缩
if ((szSource.cx > = fWidth)||(szSource.cy > = fHeight))
{
// 收缩
if (fPercentCx > fPercentCy)
{
// 必须水平缩小
fNewWidth =((szSource.cx * fPercentCy)/ 100 );
if (uiAlign& DT_CENTER)
fLeft + =((fWidth - fNewWidth)/ 2 );
else if (uiAlign& DT_RIGHT)
fLeft + =(fWidth - fNewWidth);
fWidth = fNewWidth;
}
其他
{
// < span class =code-comment>必须垂直缩小

fNewHeight =((szSource.cy * fPercentCx)/ 100 );
if (uiAlign& DT_VCENTER)
fTop + =((fHeight - fNewHeight)/ 2 );
else if (uiAlign& DT_BOTTOM)
fTop + =(fHeight - fNewHeight);
fHeight = fNewHeight;
}
}
else
{
// 拉伸
如果(fPercentCx > fPercentCy)
{
// 必须水平延伸
float fNewWidth =((szSource.cx * fPercentCy)/ 100 );
if (uiAlign& DT_CENTER)
fLeft + =((fWidth - fNewWidth)/ 2 );
else if (uiAlign& DT_RIGHT)
fLeft + =(fWidth - fNewWidth);
fWidth = fNewWidth;
}
其他
{
// < span class =code-comment>必须垂直拉伸

float fNewHeight =((szSource.cy * fPercentCx)/ 100 );
if (uiAlign& DT_VCENTER)
fTop + =((fHeight - fNewHeight)/ 2 );
else if (uiAlign& DT_BOTTOM)
fTop + =(fHeight - fNewHeight);
fHeight = fNewHeight;
}
}

return CRect(( int )fLeft,( int )fTop,( int )(fLeft + fWidth),( int )(fTop + fHeight));
}


A 1920 x 1080 image is a 16:9 aspect ratio. I can put the image into a D3DImage no problem. I am using this as the background of a Canvas object. That works very well too. To get proper scaling when the Canvas is resized by the user changing the size of the Window I have the Canvas inside a ViewBox.

My question is if the Canvas was set to a size that is a 16:9 aspect ratio, say 640 x 360, when the ViewBox resizes the Canvas will that aspect ratio be maintained?

This ties into my other question Common Coordinates for a D3DImage in a Canvas[^]

@BillWoodruff, my apologies, this is a WPF/DirectX question.

@Sergey, what you say makes sense but the ViewBox seems to take care of this.

It really strange. When I get the Height/Width/PixelHeight or PixelWidth the D3DImage always reports 1920 x 1080 no matter what happens to it visually on the screen, yet it always looks correct as long as I start with a Cavas size that is a 16:9 ratio. Also the Canvas never get an event indicating it has been resize yet the ViewBox does.
Thanks,
Doug

解决方案

You have to support it in code. Take bounding rectangle and consider two separate cases: if its aspect ratio bigger or smaller then the target one. In one case you can create two vertical unused bands on left and right, on second case — two horizontal bands on top and bottom. The same aspect ratio of the bounding rectangle and the target one will be the special case of one of those cases; this is your choice; in this case, the image will occupy the whole area of the bounding rectangle.

—SA


Here's an aspect ratio function I use written in C++, you can easily convert it I imagine.

inline CRect GetTargetRect(CRect rTarget, CSize szSource,
    unsigned int uiAlign = DT_CENTER|DT_VCENTER)
{
    // Keep the aspect ratio
    float fLeft = (float)rTarget.left;
    float fTop = (float)rTarget.top;
    float fWidth = (float)rTarget.Width();
    float fHeight = (float)rTarget.Height();
    float fPercentCy = ((fHeight / szSource.cy) * 100);
    float fPercentCx = ((fWidth / szSource.cx) * 100);
    float fNewWidth = 0;
    float fNewHeight = 0;

    // See if were stretching or shrinking
    if((szSource.cx >= fWidth) || (szSource.cy >= fHeight))
    {
        // Shrinking
        if(fPercentCx > fPercentCy)
        {
            // Must shrink more horizontally
            fNewWidth = ((szSource.cx * fPercentCy) / 100);
            if(uiAlign & DT_CENTER)
                fLeft += ((fWidth - fNewWidth) / 2);
            else if(uiAlign & DT_RIGHT)
                fLeft += (fWidth - fNewWidth);
            fWidth = fNewWidth;
        }
        else
        {
            // Must shrink more vertically
            fNewHeight = ((szSource.cy * fPercentCx) / 100);
            if(uiAlign & DT_VCENTER)
                fTop += ((fHeight - fNewHeight) / 2);
            else if(uiAlign & DT_BOTTOM)
                fTop += (fHeight - fNewHeight);
            fHeight = fNewHeight;
        }
    }
    else
    {
        // Stretching
        if(fPercentCx > fPercentCy)
        {
            // Must stretch more horizontally
            float fNewWidth = ((szSource.cx * fPercentCy) / 100);
            if(uiAlign & DT_CENTER)
                fLeft += ((fWidth - fNewWidth) / 2);
            else if(uiAlign & DT_RIGHT)
                fLeft += (fWidth - fNewWidth);
            fWidth = fNewWidth;
        }
        else
        {
            // Must stretch more vertically
            float fNewHeight = ((szSource.cy * fPercentCx) / 100);
            if(uiAlign & DT_VCENTER)
                fTop += ((fHeight - fNewHeight) / 2);
            else if(uiAlign & DT_BOTTOM)
                fTop += (fHeight - fNewHeight);
            fHeight = fNewHeight;
        }
    }

    return CRect((int)fLeft, (int)fTop, (int)(fLeft + fWidth), (int)(fTop + fHeight));
}


这篇关于保持纵横比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆