سؤال

I'm really weak with math and having a problem with an image resize algorithm. I'm trying to resize an image to a a specific ratio.

double neededRatio = 1.6d;
while (!AboutEqual(imageRatio, neededRatio))
{
    var cropPixels = 10;
    //crop code
    ...
    imageRatio = (double)img.Width / img.Height;
}

public static bool AboutEqual(double x, double y)
{
    double epsilon = Math.Max(Math.Abs(x), Math.Abs(y)) * 1E-15;
    return Math.Abs(x - y) <= epsilon;
}

The problem is, I can't seem to find the right number of pixels to crop to actually make the AboutEqual method work (I found it here). Sometimes it fails and the image get cropped indefinitely, I tried to log the inner-workings of the AboutEqual method and it's showing things I find weird, like:

X: 1.5249500998004  Y: 1.6 result: false
X: 1.55600814663951 Y: 1.6 result: false
X: 1.55600814663951 Y: 1.6 result: false
X: 1.58835758835759 Y: 1.6 result: false
X: 1.62208067940552 Y: 1.6 result: false
X: 1.60084925690021 Y: 1.6 result: false
X: 1.5796178343949  Y: 1.6 result: false
X: 1.61388286334056 Y: 1.6 result: false
X: 1.59219088937093 Y: 1.6 result: false
X: 1.62749445676275 Y: 1.6 result: false
X: 1.60532150776053 Y: 1.6 result: false
X: 1.58314855875831 Y: 1.6 result: false
X: 1.61904761904762 Y: 1.6 result: false
X: 1.59637188208617 Y: 1.6 result: false
X: 1.63341067285383 Y: 1.6 result: false

The linked question says "If both x and y are computed values then you have to increase the epsilon." - How do I do that and find the best number of pixels to crop?

هل كانت مفيدة؟

المحلول

You don't need to iterate to get your value. Calculate the target x value which would give you the desired ratio, and remove extra pixels.

Presuming that x is too large and you want to crop it:

// x/y should be 1.6
double neededRatio = 1.6d;

// so if we know y, then x should be:
int xTarget = (int)Math.Round(y * neededRatio);

// pixels to crop
int pixelsToCrop = x - xTarget;

[Edit]

The point is, this code gets the target x you will need to get to (presuming you need the ratio). If you still thing you need a loop, nothing stops you from doing:

while (x > xTarget)
{
    // crop 10 pixels
    // and do magic stuff
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top