如何将缩放图像上的XY坐标和高度/宽度转换为原始大小的图像?

sco*_*ttm 11 c# image-scaling

相关问题

我试图做与链接问题相同的事情,但使用C#.我正在显示缩放图像,并允许用户选择要裁剪的区域.但是,我不能从缩放的图像选择中获取x1y1,x2y2坐标并从原始图像中裁剪出来.我试过像其他问题那样做一些基本的数学,但这显然也不是正确的方法(它肯定更接近).

编辑

原始图像尺寸: w = 1024 h = 768

缩放图像尺寸: w = 550 h = 412

我从图像开始,比如1024x768.我希望它在550x550的盒子中尽可能大.我正在使用以下方法来获得缩放的图像大小(同时保持纵横比).然后我对这些新维度进行基本调整.

对于选择区域,它可以是任何(0,0)到(100,100).

private static Rectangle MaintainAspectRatio(Image imgPhoto, Rectangle thumbRect)
{
    int sourceWidth = imgPhoto.Width; int sourceHeight = imgPhoto.Height; int sourceX = 0; int sourceY = 0; int destX = 0; int destY = 0;

    float nPercent = 0;
    float nPercentW = 0;
    float nPercentH = 0;

    nPercentW = ((float)thumbRect.Width / (float)sourceWidth);
    nPercentH = ((float)thumbRect.Height / (float)sourceHeight);

    //if we have to pad the height pad both the top and the bottom
    //with the difference between the scaled height and the desired height
    if (nPercentH < nPercentW)
    {
        nPercent = nPercentH;
        destX = (int)((thumbRect.Width - (sourceWidth * nPercent)) / 2);
    }
    else
    {
        nPercent = nPercentW;
        destY = (int)((thumbRect.Height - (sourceHeight * nPercent)) / 2);
    }

    int destWidth = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);

    Rectangle retRect = new Rectangle(thumbRect.X, thumbRect.Y, destWidth, destHeight);
    return retRect;
}
Run Code Online (Sandbox Code Playgroud)

Mat*_*lie 9

没有更多细节,我猜你实际上正在遭受舍入错误...
- 当你将(顶部,左侧)坐标缩放回原始坐标时,你需要向下舍入(向左上方) ).
- 当您将(底部,右侧)坐标缩放回原始坐标时,需要向上舍入(向右下方)

举一个简单的例子,12x12网格作为原始版本,4x4网格作为缩放版本.
- (1,1):( 2,2)上的缩放版本=(3,3):( 8,8)
- 2×2像素的缩放版本的面积= 25%
- 6×6像素的区域的= 25%原始版本

如果要简单地乘以相同的缩放因子,这将给出(3,3):( 6,6).


OriginalTop = INT(ScaledTop*YScalingFactor);
OriginalLeft = INT(ScaledLeft*XScalingFactor);

OriginalBottom = INT((ScaledBottom + 1)*YScalingFactor) - 1;
OriginalRight = INT((ScaledRight + 1)*XScalingFactor) - 1;


编辑:

解释我想说的内容的更好方法是绘制图片.我吮吸ASCII艺术.所以这是另一个用文字的尝试.

像素不是一个点.它本身就是一个小矩形.

当您使用像素来表示矩形的左上角时,您将包括像素左上角的最大点的区域.

当您使用像素来表示右下矩形的,你包括区域一路到右下最点像素.


再次使用(12x12)=>(4x4)示例,每个缩放像素表示原始像素中的整个3x3像素集.在谈到左上角时,您选择原始中3x3像素组的左上角像素.当谈到右下角时,你会选择原始中3x3像素组的右下角.


编辑:只使用整数.

NewTop    = ((   OldTop    ) * NewHeight / OldHeight);
NewLeft   = ((   OldLeft   ) * NewWidth  / OldWidth );

NewBottom = ((OldBottom + 1) * NewHeight / OldHeight) - 1;
NewRight  = ((OldRight  + 1) * NewWidth  / OldWidth ) - 1;
Run Code Online (Sandbox Code Playgroud)


唯一的考虑因素是确保在乘法后不会溢出数据类型.但是对于图像,你不会,除非它是一个图像的地狱.