mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-24 04:09:29 +01:00
More reliable float->fraction conversion, fixed manual fps input
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Windows.Navigation;
|
||||
|
||||
namespace Flowframes.Data
|
||||
{
|
||||
@@ -42,9 +43,9 @@ namespace Flowframes.Data
|
||||
|
||||
public Fraction(float value)
|
||||
{
|
||||
int[] frac = value.ToFraction();
|
||||
Numerator = frac[0];
|
||||
Denominator = frac[1];
|
||||
Numerator = (value * 10000f).RoundToInt();
|
||||
Denominator = 10000;
|
||||
this = GetReduced();
|
||||
}
|
||||
|
||||
public Fraction(string text)
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Flowframes.Data;
|
||||
|
||||
namespace Flowframes
|
||||
{
|
||||
@@ -185,57 +186,5 @@ namespace Flowframes
|
||||
{
|
||||
return str.Split(new string[] { trimStr }, StringSplitOptions.None);
|
||||
}
|
||||
|
||||
public static int[] ToFraction(this float value, double accuracy = 0.02)
|
||||
{
|
||||
int sign = Math.Sign(value);
|
||||
|
||||
if (sign == -1)
|
||||
value = Math.Abs(value);
|
||||
|
||||
// Accuracy is the maximum relative error; convert to absolute maxError
|
||||
double maxError = sign == 0 ? accuracy : value * accuracy;
|
||||
|
||||
int n = (int)Math.Floor(value);
|
||||
value -= n;
|
||||
|
||||
if (value < maxError)
|
||||
return new int[] { sign * n, 1 };
|
||||
|
||||
if (1 - maxError < value)
|
||||
return new int[] { sign * (n + 1), 1 };
|
||||
|
||||
// The lower fraction is 0/1
|
||||
int lower_n = 0;
|
||||
int lower_d = 1;
|
||||
|
||||
// The upper fraction is 1/1
|
||||
int upper_n = 1;
|
||||
int upper_d = 1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// The middle fraction is (lower_n + upper_n) / (lower_d + upper_d)
|
||||
int middle_n = lower_n + upper_n;
|
||||
int middle_d = lower_d + upper_d;
|
||||
|
||||
if (middle_d * (value + maxError) < middle_n)
|
||||
{
|
||||
// real + error < middle : middle is our new upper
|
||||
upper_n = middle_n;
|
||||
upper_d = middle_d;
|
||||
}
|
||||
else if (middle_n < (value - maxError) * middle_d)
|
||||
{
|
||||
// middle < real - error : middle is our new lower
|
||||
lower_n = middle_n;
|
||||
lower_d = middle_d;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new int[] {(n * middle_d + middle_n) * sign, middle_d};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,6 +288,9 @@ namespace Flowframes
|
||||
{
|
||||
float fpsOut = fpsInTbox.GetFloat() * interpFactorCombox.GetFloat();
|
||||
fpsOutTbox.Text = fpsOut.ToString();
|
||||
|
||||
if (!fpsInTbox.ReadOnly)
|
||||
currInFps = new Fraction(fpsInTbox.GetFloat());
|
||||
}
|
||||
|
||||
private void interpFactorCombox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Flowframes.Media
|
||||
if (logMode != LogMode.Hidden)
|
||||
Logger.Log((resampleFps <= 0) ? $"Encoding GIF..." : $"Encoding GIF resampled to {resampleFps.ToString().Replace(",", ".")} FPS...");
|
||||
string vfrFilename = Path.GetFileName(framesFile);
|
||||
string paletteFilter = palette ? $"-vf \"split[s0][s1];[s0]palettegen={colors}[p];[s1][p]paletteuse=dither=bayer\"" : "";
|
||||
string paletteFilter = palette ? $"-vf \"split[s0][s1];[s0]palettegen={colors}[p];[s1][p]paletteuse=dither=bayer:bayer_scale=2\"" : "";
|
||||
string fpsFilter = (resampleFps <= 0) ? "" : $"fps=fps={resampleFps.ToStringDot()}";
|
||||
string vf = FormatUtils.ConcatStrings(new string[] { paletteFilter, fpsFilter });
|
||||
string args = $"-f concat -r {rate} -i {vfrFilename.Wrap()} -f gif {vf} {outPath.Wrap()}";
|
||||
|
||||
Reference in New Issue
Block a user