我怎样才能改变XY坐标和高度/宽度缩放图像到原始大小的图像? [英] How can I transform XY coordinates and height/width on a scaled image to an original sized image?

查看:766
本文介绍了我怎样才能改变XY坐标和高度/宽度缩放图像到原始大小的图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关问题



我试图做同样的事情在链接的问题,但与C#。我显示经缩放图像和上午允许用户选择要裁剪的区域。但是,我不能只是采取X1Y1,X2Y2从缩放后的图像选择和作物,从原来的坐标。我试着做一些基本的数学像其他的问题,但是这显然不是正确的做法是(这绝对是更接近)。



修改



原始图像尺寸: W = 1024 H = 768



缩放图像尺寸: W = 550 H = 412



我开始与图像,说1024×768。我希望它在550x550箱子里已装不下尽可能大。我用下面的方法来获取缩放后的图像尺寸(同时保持纵横比)。然后我做一个基本的大小调整到这些新的尺寸。



作为选择区,它可以是任何东西(0,0)到(100,100)。



 私有静态矩形MaintainAspectRatio(图片imgPhoto,矩形thumbRect)
{
INT sourceWidth = imgPhoto.Width; INT sourceHeight = imgPhoto.Height; INT sourceX = 0; INT sourceY = 0; INT destX = 0; INT destY = 0;

浮动nPercent = 0;
浮动nPercentW = 0;
浮动nPercentH = 0;

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

//如果我们有垫的高度垫的顶部和底部
//与经缩放的高度和希望的高度
如果(nPercentH℃之间的差nPercentW)
{
nPercent = nPercentH;
destX =(int)的((thumbRect.Width - (sourceWidth * nPercent))/ 2);
}
,否则
{
nPercent = nPercentW;
destY =(int)的((thumbRect.Height - (sourceHeight * nPercent))/ 2);
}

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

矩形retRect =新的Rectangle(thumbRect.X,thumbRect.Y,destWidth,destHeight);
返回retRect;
}


解决方案

如果没有更多的细节,我猜你实际上是从舍入误差......结果
痛苦 - 当你缩放(顶部,左侧)统筹回原来的,你需要四舍五入(朝上方左)结果
- 当你缩放(底部,右)统筹回原来的,你需要围捕(朝向右下方)



以一个12×12网格作为原始,和一个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艺术。因此,这里的文字另一个尝试。



一个像素不是一个点。这是在它自己右边的小矩形。



当你用像素来表示一个矩形的左上角,你包括从左上角大部分面积像素点。



当你用像素来表示一个长方形的右下,你包括该地区所有的方式到右下大多数像素点。



结果



使用(12×12)=>(4×4)再比如,每一个缩放像素代表一个整体的3x3集原始像素。在谈到左上角,你选择在原来的3×3像素组的左上角像素。和谈论右下方的时候,你选择在原来的3×3像素组的右下方。



结果



修改:只需使用整数

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

NewBottom =((OldBottom + 1)* NewHeight / OldHeight) - 1;
NewRight =((OldRight + 1)* NewWidth / OldWidth) - 1;



结果



唯一要考虑的是确保你不乘后溢出的数据类型。但随着影像,你不会,除非它是一个图像的地狱。


Related Question

I am trying to do the same thing as in the linked question, but with C#. I am showing a scaled image and am allowing a user to select an area to crop. However, I can't just take the x1y1, x2y2 coordinates from the scaled image selection and crop that from the original. I've tried doing some basic math like in the other question, but that's obviously not the right approach either (it's definitely closer).

Edit

Original Image Dimensions: w = 1024 h = 768

Scaled Image Dimensions: w = 550 h = 412

I start with an image, say 1024x768. I want it to fit as large as possible in a 550x550 box. I'm using the following method to get the scaled image size (while maintaining aspect ratio). Then I do a basic resize to those new dimensions.

As for a selection area, it can be anything (0,0) to (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;
}

解决方案

Without a bit more detail, I'm guessing that you're actually suffering from rounding errors...
- When you scale the (top,left) co-ordinate back to the original, you need to round down (towards the top left).
- When you scale the (bottom,right) co-ordinate back to the original, you need to round up (towards the bottom right)

Take a simple example of a 12x12 grid as the original, and a 4x4 grid as the scaled version.
- (1,1):(2,2) on the scaled version = (3,3):(8,8)
- 2x2 pixel = 25% of the area of the scaled version
- 6x6 pixel = 25% of the area of the original version

If one was to simply multiply by the same scaling factors, this would give (3,3):(6,6).


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

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


EDIT:

A better way of explaining what I'm trying to say would be to draw a picutre. And I suck at ASCII Art. So here's another try with words.

A pixel isn't a point. It's a small rectangle in it's own right.

When you use a pixel to represent the top left of a rectangle, you're including the area from the top-left most Point of the pixel.

When you use a pixel to represent the Bottom Right of a rectangle, you're including the area all the way to the Bottom Right most Point of the pixel.


Using the (12x12) => (4x4) example again, every scaled pixel represents a whole 3x3 set of pixels in the original. When talking about the top left, you pick the top left pixel of the 3x3 pixel group in the original. And when talking about the bottom right, you pick the bottom right of the 3x3 pixel group in the original.


EDIT: Using just integers.

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

NewBottom = ((OldBottom + 1) * NewHeight / OldHeight) - 1;
NewRight  = ((OldRight  + 1) * NewWidth  / OldWidth ) - 1;


The only consideration is making sure that you don't overflow your data type after the multiplication. But with images, you won't, unless it's a hell of an image.

这篇关于我怎样才能改变XY坐标和高度/宽度缩放图像到原始大小的图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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