如何将缩放图像上的XY坐标和高度/宽度转换为原始大小的图像?
相关问题
我试图做与链接问题相同的事情,但使用C#。 我正在显示缩放图像,并允许用户选择要裁剪的区域。 但是,我不能从缩放的图像选择中获取x1y1,x2y2坐标并从原始图像中裁剪出来。 我试过像其他问题那样做一些基本的数学,但这显然不是正确的方法(它肯定更接近)。
编辑
原始图像尺寸: w = 1024 h = 768
缩放图像尺寸: w = 550 h = 412
我从图像开始,比如1024×768。 我希望它在550×550的盒子中尽可能大。 我正在使用以下方法来获得缩放的图像大小(同时保持纵横比)。 然后我对这些新维度进行基本调整。
对于选择区域,它可以是任何(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; }
没有更多的细节,我猜你实际上正在遭受舍入错误……
– 当您将(顶部,左侧)坐标缩放回原始坐标时,您需要向下舍入(向左上方)。
– 当您将(底部,右侧)坐标缩放回原始坐标时,您需要向上舍入(向右下方)
举一个简单的例子,12×12网格作为原始版本,4×4网格作为缩放版本。
– (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艺术。 所以这是另一个用文字尝试。
像素不是一个点。 它本身就是一个小矩形。
当您使用像素表示矩形的左上角时,您将包括像素左上角的最大点的区域。
当您使用像素表示矩形的右下角时,您将该区域一直包含在像素的最右下角。
再次使用(12×12)=>(4×4)示例,每个缩放像素表示原始像素中的整个3×3像素集。 在谈到左上角时,您选择原始中3×3像素组的左上角像素。 在谈到右下角时,您选择原始中3×3像素组的右下角。
编辑 :只使用整数。
NewTop = (( OldTop ) * NewHeight / OldHeight); NewLeft = (( OldLeft ) * NewWidth / OldWidth ); NewBottom = ((OldBottom + 1) * NewHeight / OldHeight) - 1; NewRight = ((OldRight + 1) * NewWidth / OldWidth ) - 1;
唯一的考虑因素是确保在乘法后不会溢出数据类型。 但是对于图像,你不会,除非它是一个图像的地狱。
您可以获取缩放图像的百分比位置,并将它们转换为未缩放图像的坐标:
pX1 = scaledX1/scaled_width pY1 = scaledY1/scaled_height unscaledX1 = ceiling(unscaled_width * pX1) unscaledY1 = ceiling(unscaled_height * pY1)