Improved alpha support

This commit is contained in:
N00MKRAD
2021-01-27 11:41:05 +01:00
parent 3d2a244643
commit 40e63fe51d
7 changed files with 80 additions and 36 deletions

View File

@@ -16,7 +16,6 @@ namespace Flowframes
{
class FFmpegCommands
{
static string hdrFilter = @"-vf select=gte(n\,%frNum%),zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p";
static string divisionFilter = "\"pad=width=ceil(iw/2)*2:height=ceil(ih/2)*2:color=black@0\"";
static string pngComprArg = "-compression_level 3";
static string mpDecDef = "\"mpdecimate\"";
@@ -44,7 +43,7 @@ namespace Flowframes
string timecodeStr = timecodes ? $"-copyts -r {FrameOrder.timebase} -frame_pts true" : "-copyts -frame_pts true";
string scnDetect = sceneDetect ? $"\"select='gt(scene,{Config.GetFloatString("scnDetectValue")})'\"" : "";
string mpStr = deDupe ? ((Config.GetInt("mpdecimateMode") == 0) ? mpDecDef : mpDecAggr) : "";
string filters = FormatUtils.ConcatStrings(new string[] { scnDetect, mpStr } );
string filters = FormatUtils.ConcatStrings(new string[] { divisionFilter, scnDetect, mpStr } );
string vf = filters.Length > 2 ? $"-vf {filters}" : "";
string rateArg = (rate > 0) ? $" -r {rate.ToStringDot()}" : "";
string pixFmt = alpha ? "-pix_fmt rgba" : "-pix_fmt rgb24"; // Use RGBA for GIF for alpha support

View File

@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Flowframes.IO
{
@@ -13,11 +10,7 @@ namespace Flowframes.IO
public const string interpDir = "interp";
public const string chunksDir = "vchunks";
public const string scenesDir = "scenes";
public static void Init()
{
}
public const string alphaSuffix = "-a";
public static string GetVerPath()
{

View File

@@ -513,9 +513,9 @@
this.label25.Location = new System.Drawing.Point(10, 70);
this.label25.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label25.Name = "label25";
this.label25.Size = new System.Drawing.Size(108, 13);
this.label25.Size = new System.Drawing.Size(177, 13);
this.label25.TabIndex = 76;
this.label25.Text = "Enable Transparency";
this.label25.Text = "Enable Transparency (Experimental)";
//
// keepSubs
//

View File

@@ -36,11 +36,45 @@ namespace Flowframes.Magick
}
}
public static async Task ExtractAlpha (string inputDir, string outputDir, bool print = true, bool setProgress = true)
public static async Task MakeBinary (string inputDir, string outputDir, bool print = true, bool setProgress = true)
{
try
{
var files = IOUtils.GetFilesSorted(inputDir);
if (print) Logger.Log($"Processing alpha channel...");
Directory.CreateDirectory(outputDir);
Stopwatch sw = new Stopwatch();
sw.Restart();
int counter = 0;
foreach (string file in files)
{
MagickImage img = new MagickImage(file);
img.Format = MagickFormat.Png24;
img.Quality = 10;
img.Threshold(new Percentage(90));
string outPath = Path.Combine(outputDir, Path.GetFileName(file));
img.Write(outPath);
counter++;
if (sw.ElapsedMilliseconds > 250)
{
if (setProgress)
Program.mainForm.SetProgress((int)Math.Round(((float)counter / files.Length) * 100f));
await Task.Delay(1);
sw.Restart();
}
}
}
catch (Exception e)
{
Logger.Log("ExtractAlpha Error: " + e.Message);
}
}
public static async Task ExtractAlpha (string inputDir, string outputDir, bool print = true, bool setProgress = true, bool removeInputAlpha = true)
{
try
{
var files = IOUtils.GetFilesSorted(inputDir);
if (print) Logger.Log($"Extracting alpha channel from images...");
Directory.CreateDirectory(outputDir);
@@ -49,16 +83,28 @@ namespace Flowframes.Magick
int counter = 0;
foreach (string file in files)
{
MagickImage img = new MagickImage(file);
img.Format = MagickFormat.Png32;
img.Quality = 10;
MagickImage alphaImg = new MagickImage(file);
if (removeInputAlpha)
{
MagickImage rgbImg = alphaImg;
rgbImg.Format = MagickFormat.Png24;
rgbImg.Quality = 10;
MagickImage bg = new MagickImage(MagickColors.Black, rgbImg.Width, rgbImg.Height);
bg.Composite(rgbImg, CompositeOperator.Over);
rgbImg = bg;
rgbImg.Write(file);
}
alphaImg.Format = MagickFormat.Png24;
alphaImg.Quality = 10;
img.FloodFill(MagickColors.None, 0, 0); // Fill the image with a transparent background
img.InverseOpaque(MagickColors.None, MagickColors.White); // Change all the pixels that are not transparent to white.
img.ColorAlpha(MagickColors.Black); // Change the transparent pixels to black.
alphaImg.FloodFill(MagickColors.None, 0, 0); // Fill the image with a transparent background
alphaImg.InverseOpaque(MagickColors.None, MagickColors.White); // Change all the pixels that are not transparent to white.
alphaImg.ColorAlpha(MagickColors.Black); // Change the transparent pixels to black.
string outPath = Path.Combine(outputDir, Path.GetFileName(file));
img.Write(outPath);
alphaImg.Write(outPath);
counter++;
if (sw.ElapsedMilliseconds > 250)
{

View File

@@ -86,7 +86,7 @@ namespace Flowframes
Program.mainForm.SetStatus("Extracting frames from video...");
bool mpdecimate = Config.GetInt("dedupMode") == 2;
await FFmpegCommands.VideoToFrames(inPath, outPath, alpha, current.inFps, mpdecimate, false, await Utils.GetOutputResolution(inPath, true), false);
await FFmpegCommands.VideoToFrames(inPath, outPath, alpha, current.inFps, mpdecimate, false, await Utils.GetOutputResolution(inPath, true, true), false);
if (mpdecimate)
{

View File

@@ -327,9 +327,6 @@ namespace Flowframes.Main
{
if (videoPath == null || !IOUtils.IsFileValid(videoPath))
return false;
// string ext = Path.GetExtension(videoPath).ToLower();
// if (!Formats.supported.Contains(ext))
// return false;
return true;
}
@@ -340,13 +337,13 @@ namespace Flowframes.Main
Logger.Log("Message: " + msg, true);
}
public static async Task<Size> GetOutputResolution (string inputPath, bool print)
public static async Task<Size> GetOutputResolution (string inputPath, bool print, bool returnZeroIfUnchanged = false)
{
Size resolution = await IOUtils.GetVideoOrFramesRes(inputPath);
return GetOutputResolution(resolution, print);
return GetOutputResolution(resolution, print, returnZeroIfUnchanged);
}
public static Size GetOutputResolution(Size inputRes, bool print = false)
public static Size GetOutputResolution(Size inputRes, bool print = false, bool returnZeroIfUnchanged = false)
{
int maxHeight = RoundDiv2(Config.GetInt("maxVidHeight"));
if (inputRes.Height > maxHeight)
@@ -360,7 +357,11 @@ namespace Flowframes.Main
}
else
{
return new Size(RoundDiv2(inputRes.Width), RoundDiv2(inputRes.Height));
//return new Size(RoundDiv2(inputRes.Width), RoundDiv2(inputRes.Height));
if (returnZeroIfUnchanged)
return new Size();
else
return inputRes;
}
}

View File

@@ -12,6 +12,7 @@ using Flowframes.UI;
using Flowframes.Main;
using Flowframes.Data;
using Flowframes.MiscUtils;
using Flowframes.Magick;
namespace Flowframes
{
@@ -76,6 +77,17 @@ namespace Flowframes
await Task.Delay(500);
}
if (!Interpolate.canceled && Interpolate.current.alpha)
{
Logger.Log("Processing alpha...");
string rgbInterpDir = Path.Combine(Interpolate.current.tempFolder, Paths.interpDir);
string alphaInterpDir = Path.Combine(Interpolate.current.tempFolder, Paths.interpDir + Paths.alphaSuffix);
if (!Directory.Exists(alphaInterpDir)) return;
if (Interpolate.current.outMode == Interpolate.OutMode.VidGif)
await Converter.MakeBinary(alphaInterpDir, alphaInterpDir, false); // Apply threshold if output has binary alpha
await FFmpegCommands.MergeAlphaIntoRgb(rgbInterpDir, Padding.interpFrames, alphaInterpDir, Padding.interpFrames);
}
}
public static async Task RunRifeCuda(string framesPath, int interpFactor, string mdl)
@@ -95,17 +107,10 @@ namespace Flowframes
{
InterpolateUtils.progressPaused = true;
Logger.Log("Interpolating alpha channel...");
await RunRifeCudaProcess(framesPath + "-a", Paths.interpDir + "-a", script, interpFactor, mdl);
await RunRifeCudaProcess(framesPath + Paths.alphaSuffix, Paths.interpDir + Paths.alphaSuffix, script, interpFactor, mdl);
}
await AiFinished("RIFE");
if (!Interpolate.canceled && Interpolate.current.alpha)
{
Logger.Log("Processing alpha...");
string rgbInterpDir = Path.Combine(Interpolate.current.tempFolder, Paths.interpDir);
await FFmpegCommands.MergeAlphaIntoRgb(rgbInterpDir, Padding.interpFrames, rgbInterpDir + "-a", Padding.interpFrames);
}
}
public static async Task RunRifeCudaProcess (string inPath, string outDir, string script, int interpFactor, string mdl)