From 5e4e907a2c6a45423ec334e8b0d07c26c0e98f90 Mon Sep 17 00:00:00 2001 From: "Emrick, Joshua" Date: Mon, 15 Jun 2026 09:50:26 -0400 Subject: [PATCH] Add resolution-aware subtitle scaling and configurable layout defaults - replace fixed RG subtitle bottom positioning with resolution-scaled Y offset - add centralized ScaleX, ScaleY, and ScaleFont helpers - scale RG horizontal eye offset based on output width - scale font size, SBS margins, and OU margins based on output/base resolution - change default baseline behavior from legacy 384x288 to tunable base resolution - add BaseResX/BaseResY options with 1280x720 defaults - add CLI options for: - --baseresx - --baseresy - --bottomoffset - --sbssidemargin - --outopmargin - --verticalmargin - replace remaining layout magic numbers with configurable options: - BottomOffset - SbsSideMargin - OuTopMargin - VerticalMargin - FontSize - OffsetX - preserve original numeric defaults for layout settings when not specified (based off of my personal experiences and preferences. - update WinForms designer to expose new converter settings - update WinForms code-behind to pass new options to Converter.Main - prefill GUI controls with converter-aligned default values - improve mode-based UI enable/disable behavior for SBS, OU, and RG settings - prepare shared-defaults approach via ConverterDefaults for keeping GUI and converter defaults in sync --- ConvertSRTto3DASS/Converter.cs | 249 ++++++++++++++++++------- ConvertSRTto3DASSGUI/Form1.Designer.cs | 243 ++++++++++++++++++++++-- ConvertSRTto3DASSGUI/Form1.cs | 109 +++++++++-- 3 files changed, 510 insertions(+), 91 deletions(-) diff --git a/ConvertSRTto3DASS/Converter.cs b/ConvertSRTto3DASS/Converter.cs index 7f9bd58..07ed217 100644 --- a/ConvertSRTto3DASS/Converter.cs +++ b/ConvertSRTto3DASS/Converter.cs @@ -16,20 +16,67 @@ namespace ConvertSRTto3DASS { SBS, OU, - RG //Experimental + RG // Experimental + } + + public static class ConverterDefaults + { + /// + ///720 as default is arbitary,it's my favorite resolution for space saving and most mobile 3d viewing doesn't benefit from much higher (IE google cardboard or Meta Quest Headset). + /// + public const int ResX = 1280; + public const int ResY = 720; + + public const int BaseResX = 1280; + public const int BaseResY = 720; + + public const int FontSize = 16; + public const int OffsetX = 4; + public const int BottomOffset = 18; + public const int SbsSideMargin = 640; + public const int OuTopMargin = 385; + public const int VerticalMargin = 25; + + public const string DefaultMode = "sbs"; } private class Options { public string InputPath { get; set; } public string OutputPath { get; set; } + public StereoMode Mode { get; set; } = StereoMode.SBS; - public int ResX { get; set; } = 384; - public int ResY { get; set; } = 288; - public int FontSize { get; set; } = 16; - public int OffsetX { get; set; } = 4; // used for RG anaglyph + + public int ResX { get; set; } = ConverterDefaults.ResX; + public int ResY { get; set; } = ConverterDefaults.ResY; + public int BaseResX { get; set; } = ConverterDefaults.BaseResX; + public int BaseResY { get; set; } = ConverterDefaults.BaseResY; + public int FontSize { get; set; } = ConverterDefaults.FontSize; + public int OffsetX { get; set; } = ConverterDefaults.OffsetX; + public int BottomOffset { get; set; } = ConverterDefaults.BottomOffset; + public int SbsSideMargin { get; set; } = ConverterDefaults.SbsSideMargin; + public int OuTopMargin { get; set; } = ConverterDefaults.OuTopMargin; + public int VerticalMargin { get; set; } = ConverterDefaults.VerticalMargin; } + private static readonly Dictionary RegexReplacementDict = + new Dictionary + { + { new Regex("", RegexOptions.IgnoreCase), "{\\b1}" }, + { new Regex("", RegexOptions.IgnoreCase), "{\\b0}" }, + { new Regex("", RegexOptions.IgnoreCase), "{\\i1}" }, + { new Regex("", RegexOptions.IgnoreCase), "{\\i0}" }, + { new Regex("", RegexOptions.IgnoreCase), "{\\u1}" }, + { new Regex("", RegexOptions.IgnoreCase), "{\\u0}" }, + { new Regex("", RegexOptions.IgnoreCase), "{\\c&HFFFFFF&}" } + }; + + private static readonly Regex ColorRegex = + new Regex("", RegexOptions.IgnoreCase); + + private static readonly Regex RemoveFormattingRegex = + new Regex("<.+?>|(\\r)", RegexOptions.IgnoreCase); + public static void Main(string[] args) { try @@ -48,21 +95,26 @@ namespace ConvertSRTto3DASS if (string.IsNullOrWhiteSpace(options.OutputPath)) { options.OutputPath = Path.Combine( - Path.GetDirectoryName(options.InputPath) ?? "", + Path.GetDirectoryName(options.InputPath) ?? string.Empty, Path.GetFileNameWithoutExtension(options.InputPath) + ".ass"); } - Console.WriteLine("Input: " + options.InputPath); - Console.WriteLine("Output: " + options.OutputPath); - Console.WriteLine("Mode: " + options.Mode); - Console.WriteLine("Resolution: " + options.ResX + "x" + options.ResY); - Console.WriteLine("Font size: " + options.FontSize); - Console.WriteLine("OffsetX: " + options.OffsetX); + Console.WriteLine("Input: " + options.InputPath); + Console.WriteLine("Output: " + options.OutputPath); + Console.WriteLine("Mode: " + options.Mode); + Console.WriteLine("Resolution: " + options.ResX + "x" + options.ResY); + Console.WriteLine("Base Res: " + options.BaseResX + "x" + options.BaseResY); + Console.WriteLine("Font size: " + options.FontSize); + Console.WriteLine("OffsetX: " + options.OffsetX); + Console.WriteLine("BottomOffset: " + options.BottomOffset); + Console.WriteLine("SbsSideMargin: " + options.SbsSideMargin); + Console.WriteLine("OuTopMargin: " + options.OuTopMargin); + Console.WriteLine("VerticalMargin: " + options.VerticalMargin); var extracted = ExtractSubFromSRT(options.InputPath); Console.WriteLine("Subtitle blocks parsed: " + extracted.Count); - var style = CreateStandardStyle(options.Mode, options.FontSize); + var style = CreateStandardStyle(options); var header = CreateHeader(options.InputPath, options.ResY, options.ResX); var eventsText = ProcessSubs(extracted, options); @@ -74,7 +126,10 @@ namespace ConvertSRTto3DASS "\n\n[Events]\n" + eventsText; - File.WriteAllText(options.OutputPath, finished, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)); + File.WriteAllText( + options.OutputPath, + finished, + new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)); Console.WriteLine("Conversion complete."); } @@ -130,24 +185,60 @@ namespace ConvertSRTto3DASS i += 2; break; + case "--baseresx": + EnsureValueExists(args, i, "--baseresx"); + options.BaseResX = ParsePositiveInt(args[i + 1], "--baseresx"); + i += 2; + break; + + case "--baseresy": + EnsureValueExists(args, i, "--baseresy"); + options.BaseResY = ParsePositiveInt(args[i + 1], "--baseresy"); + i += 2; + break; + case "--fontsize": EnsureValueExists(args, i, "--fontsize"); options.FontSize = ParsePositiveInt(args[i + 1], "--fontsize"); i += 2; break; - case "--output": - EnsureValueExists(args, i, "--output"); - options.OutputPath = args[i + 1]; - i += 2; - break; - case "--offsetx": EnsureValueExists(args, i, "--offsetx"); options.OffsetX = ParseNonNegativeInt(args[i + 1], "--offsetx"); i += 2; break; + case "--bottomoffset": + EnsureValueExists(args, i, "--bottomoffset"); + options.BottomOffset = ParseNonNegativeInt(args[i + 1], "--bottomoffset"); + i += 2; + break; + + case "--sbssidemargin": + EnsureValueExists(args, i, "--sbssidemargin"); + options.SbsSideMargin = ParseNonNegativeInt(args[i + 1], "--sbssidemargin"); + i += 2; + break; + + case "--outopmargin": + EnsureValueExists(args, i, "--outopmargin"); + options.OuTopMargin = ParseNonNegativeInt(args[i + 1], "--outopmargin"); + i += 2; + break; + + case "--verticalmargin": + EnsureValueExists(args, i, "--verticalmargin"); + options.VerticalMargin = ParseNonNegativeInt(args[i + 1], "--verticalmargin"); + i += 2; + break; + + case "--output": + EnsureValueExists(args, i, "--output"); + options.OutputPath = args[i + 1]; + i += 2; + break; + case "--help": case "-h": case "/?": @@ -193,15 +284,23 @@ namespace ConvertSRTto3DASS Console.WriteLine(" --mode sbs|ou|rg"); Console.WriteLine(" --resx "); Console.WriteLine(" --resy "); + Console.WriteLine(" --baseresx (scaling reference width, default 1280)"); + Console.WriteLine(" --baseresy (scaling reference height, default 720)"); Console.WriteLine(" --fontsize "); - Console.WriteLine(" --offsetx (used for rg mode)"); + Console.WriteLine(" --offsetx (RG eye separation)"); + Console.WriteLine(" --bottomoffset (RG bottom offset)"); + Console.WriteLine(" --sbssidemargin (SBS side margin)"); + Console.WriteLine(" --outopmargin (OU top subtitle margin)"); + Console.WriteLine(" --verticalmargin (general vertical/bottom margin)"); Console.WriteLine(" --output "); Console.WriteLine(); Console.WriteLine("Examples:"); Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --mode sbs"); - Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --mode ou --resx 384 --resy 288"); - Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --mode rg --offsetx 4"); - Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --mode rg --fontsize 20 --output ""movie_rg.ass"""); + Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --mode ou --resx 1280 --resy 720"); + Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --mode rg --offsetx 6 --bottomoffset 24"); + Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --resx 1920 --resy 1080 --baseresx 1280 --baseresy 720"); + Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --sbssidemargin 220 --verticalmargin 16"); + Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --outopmargin 180 --fontsize 20 --output ""movie_custom.ass"""); } private static StereoMode ParseStereoMode(string mode) @@ -237,29 +336,31 @@ namespace ConvertSRTto3DASS } } - private static Dictionary regexReplacementDict = - new Dictionary { - { new Regex("", RegexOptions.IgnoreCase), "{\\b1}" }, - { new Regex("", RegexOptions.IgnoreCase), "{\\b0}" }, - { new Regex("", RegexOptions.IgnoreCase), "{\\i1}" }, - { new Regex("", RegexOptions.IgnoreCase), "{\\i0}" }, - { new Regex("", RegexOptions.IgnoreCase), "{\\u1}" }, - { new Regex("", RegexOptions.IgnoreCase), "{\\u0}" }, - { new Regex("", RegexOptions.IgnoreCase), "{\\c&HFFFFFF&}" } - }; + private static int ScaleX(int value, Options options) + { + return (int)Math.Round(value * (options.ResX / (double)options.BaseResX)); + } - private static Regex color = new Regex("", RegexOptions.IgnoreCase); + private static int ScaleY(int value, Options options) + { + return (int)Math.Round(value * (options.ResY / (double)options.BaseResY)); + } + + private static int ScaleFont(int fontSize, Options options) + { + return Math.Max(1, ScaleY(fontSize, options)); + } private static string ChangeFormatting(string line) { - foreach (var tuple in regexReplacementDict) + foreach (var tuple in RegexReplacementDict) { line = tuple.Key.Replace(line, tuple.Value); } - while (color.IsMatch(line)) + while (ColorRegex.IsMatch(line)) { - var match = color.Match(line); + var match = ColorRegex.Match(line); string rgb = match.Groups[1].Value; // RRGGBB string rr = rgb.Substring(0, 2); @@ -269,18 +370,15 @@ namespace ConvertSRTto3DASS // ASS expects BBGGRR string assColor = bb + gg + rr; - line = color.Replace(line, "{\\c&H" + assColor + "&}", 1); + line = ColorRegex.Replace(line, "{\\c&H" + assColor + "&}", 1); } return RemoveFormatting(line); } - private static Regex reg = new Regex("<.+?>|(\\r)", RegexOptions.IgnoreCase); - private static string RemoveFormatting(string line) { - var replacement = reg.Replace(line, ""); - return replacement; + return RemoveFormattingRegex.Replace(line, ""); } private static string ProcessSubs(List> srt, Options options) @@ -308,9 +406,12 @@ namespace ConvertSRTto3DASS else if (options.Mode == StereoMode.RG) { int centerX = options.ResX / 2; - int y = options.ResY - 18; // near bottom - int redX = centerX - options.OffsetX; - int greenX = centerX + options.OffsetX; + int scaledBottomOffset = ScaleY(options.BottomOffset, options); + int y = options.ResY - scaledBottomOffset; + + int scaledOffsetX = ScaleX(options.OffsetX, options); + int redX = centerX - scaledOffsetX; + int greenX = centerX + scaledOffsetX; string redText = "{\\an2\\pos(" + redX + "," + y + ")}" + text; string greenText = "{\\an2\\pos(" + greenX + "," + y + ")}" + text; @@ -331,23 +432,31 @@ namespace ConvertSRTto3DASS return tmp.Replace(",", "."); } - private static string CreateStandardStyle(StereoMode stereoMode, int fontSize) + private static string CreateStandardStyle(Options options) { - switch (stereoMode) + int scaledFontSize = ScaleFont(options.FontSize, options); + + switch (options.Mode) { case StereoMode.SBS: - return CreateSbsStyle(fontSize); + return CreateSbsStyle(scaledFontSize, options); + case StereoMode.OU: - return CreateOuStyle(fontSize); + return CreateOuStyle(scaledFontSize, options); + case StereoMode.RG: - return CreateRgStyle(fontSize); + return CreateRgStyle(scaledFontSize, options); + default: - throw new ArgumentOutOfRangeException(nameof(stereoMode)); + throw new ArgumentOutOfRangeException(nameof(options.Mode)); } } - private static string CreateSbsStyle(int fontSize) + private static string CreateSbsStyle(int fontSize, Options options) { + int sideMargin = ScaleX(options.SbsSideMargin, options); + int verticalMargin = ScaleY(options.VerticalMargin, options); + string style = "Format: " + "Name, " + @@ -394,9 +503,9 @@ namespace ConvertSRTto3DASS "1," + "0," + "2," + - "192," + + sideMargin + "," + "0," + - "10," + + verticalMargin + "," + "0\n" + "Style: " + @@ -420,15 +529,18 @@ namespace ConvertSRTto3DASS "0," + "2," + "0," + - "192," + - "10," + + sideMargin + "," + + verticalMargin + "," + "0"; return style; } - private static string CreateOuStyle(int fontSize) + private static string CreateOuStyle(int fontSize, Options options) { + int bottomMargin = ScaleY(options.VerticalMargin, options); + int topMargin = ScaleY(options.OuTopMargin, options); + string style = "Format: " + "Name, " + @@ -477,7 +589,7 @@ namespace ConvertSRTto3DASS "2," + "0," + "0," + - "154," + + topMargin + "," + "0\n" + "Style: " + @@ -502,14 +614,16 @@ namespace ConvertSRTto3DASS "2," + "0," + "0," + - "10," + + bottomMargin + "," + "0"; return style; } - private static string CreateRgStyle(int fontSize) + private static string CreateRgStyle(int fontSize, Options options) { + int verticalMargin = ScaleY(options.VerticalMargin, options); + string style = "Format: " + "Name, " + @@ -560,7 +674,7 @@ namespace ConvertSRTto3DASS "2," + "0," + "0," + - "10," + + verticalMargin + "," + "0\n" + // Green = &H00FF00 @@ -586,16 +700,17 @@ namespace ConvertSRTto3DASS "2," + "0," + "0," + - "10," + + verticalMargin + "," + "0"; return style; } - private static string CreateHeader(string file, int resY = 288, int resX = 384) + private static string CreateHeader(string file, int resY = 720, int resX = 1280) { var name = Path.GetFileNameWithoutExtension(file); - string scriptinfo = + + string scriptInfo = "; Generated by ConvertSRTto3D\n" + "Title: " + name + "\n" + "ScriptType: v4.00+\n" + @@ -604,7 +719,7 @@ namespace ConvertSRTto3DASS "PlayResY: " + resY + "\n" + "ScaledBorderAndShadow: yes"; - return scriptinfo; + return scriptInfo; } private static string ReadTextSmart(string path) @@ -654,6 +769,7 @@ namespace ConvertSRTto3DASS $"Warning: expected subtitle number {expectedDialogNumber}, but found {dialogNumber}."); expectedDialogNumber = dialogNumber; } + expectedDialogNumber++; var timeMatch = Regex.Match( @@ -668,7 +784,6 @@ namespace ConvertSRTto3DASS string timestampStart = timeMatch.Groups["start"].Value; string timestampEnd = timeMatch.Groups["end"].Value; - string subtitleText = string.Join("\\N", lines.Skip(2)); results.Add(new Tuple( diff --git a/ConvertSRTto3DASSGUI/Form1.Designer.cs b/ConvertSRTto3DASSGUI/Form1.Designer.cs index 5af3a36..96dc207 100644 --- a/ConvertSRTto3DASSGUI/Form1.Designer.cs +++ b/ConvertSRTto3DASSGUI/Form1.Designer.cs @@ -24,12 +24,30 @@ private System.Windows.Forms.Label lblResY; private System.Windows.Forms.NumericUpDown nudResY; + private System.Windows.Forms.Label lblBaseResX; + private System.Windows.Forms.NumericUpDown nudBaseResX; + + private System.Windows.Forms.Label lblBaseResY; + private System.Windows.Forms.NumericUpDown nudBaseResY; + private System.Windows.Forms.Label lblFontSize; private System.Windows.Forms.NumericUpDown nudFontSize; private System.Windows.Forms.Label lblOffsetX; private System.Windows.Forms.NumericUpDown nudOffsetX; + private System.Windows.Forms.Label lblBottomOffset; + private System.Windows.Forms.NumericUpDown nudBottomOffset; + + private System.Windows.Forms.Label lblSbsSideMargin; + private System.Windows.Forms.NumericUpDown nudSbsSideMargin; + + private System.Windows.Forms.Label lblOuTopMargin; + private System.Windows.Forms.NumericUpDown nudOuTopMargin; + + private System.Windows.Forms.Label lblVerticalMargin; + private System.Windows.Forms.NumericUpDown nudVerticalMargin; + private System.Windows.Forms.Button btnConvert; private System.Windows.Forms.TextBox txtStatus; @@ -66,16 +84,34 @@ this.nudResX = new System.Windows.Forms.NumericUpDown(); this.lblResY = new System.Windows.Forms.Label(); this.nudResY = new System.Windows.Forms.NumericUpDown(); + this.lblBaseResX = new System.Windows.Forms.Label(); + this.nudBaseResX = new System.Windows.Forms.NumericUpDown(); + this.lblBaseResY = new System.Windows.Forms.Label(); + this.nudBaseResY = new System.Windows.Forms.NumericUpDown(); this.lblFontSize = new System.Windows.Forms.Label(); this.nudFontSize = new System.Windows.Forms.NumericUpDown(); this.lblOffsetX = new System.Windows.Forms.Label(); this.nudOffsetX = new System.Windows.Forms.NumericUpDown(); + this.lblBottomOffset = new System.Windows.Forms.Label(); + this.nudBottomOffset = new System.Windows.Forms.NumericUpDown(); + this.lblSbsSideMargin = new System.Windows.Forms.Label(); + this.nudSbsSideMargin = new System.Windows.Forms.NumericUpDown(); + this.lblOuTopMargin = new System.Windows.Forms.Label(); + this.nudOuTopMargin = new System.Windows.Forms.NumericUpDown(); + this.lblVerticalMargin = new System.Windows.Forms.Label(); + this.nudVerticalMargin = new System.Windows.Forms.NumericUpDown(); this.btnConvert = new System.Windows.Forms.Button(); this.txtStatus = new System.Windows.Forms.TextBox(); ((System.ComponentModel.ISupportInitialize)(this.nudResX)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nudResY)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudBaseResX)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudBaseResY)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nudFontSize)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nudOffsetX)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudBottomOffset)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudSbsSideMargin)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudOuTopMargin)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudVerticalMargin)).BeginInit(); this.SuspendLayout(); // // lblInputFile @@ -179,7 +215,7 @@ this.nudResX.Size = new System.Drawing.Size(120, 22); this.nudResX.TabIndex = 9; this.nudResX.Value = new decimal(new int[] { - 384, + 1280, 0, 0, 0}); @@ -210,7 +246,69 @@ this.nudResY.Size = new System.Drawing.Size(120, 22); this.nudResY.TabIndex = 11; this.nudResY.Value = new decimal(new int[] { - 288, + 720, + 0, + 0, + 0}); + // + // lblBaseResX + // + this.lblBaseResX.AutoSize = true; + this.lblBaseResX.Location = new System.Drawing.Point(520, 178); + this.lblBaseResX.Name = "lblBaseResX"; + this.lblBaseResX.Size = new System.Drawing.Size(81, 16); + this.lblBaseResX.TabIndex = 12; + this.lblBaseResX.Text = "Base Res X:"; + // + // nudBaseResX + // + this.nudBaseResX.Location = new System.Drawing.Point(620, 176); + this.nudBaseResX.Maximum = new decimal(new int[] { + 10000, + 0, + 0, + 0}); + this.nudBaseResX.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.nudBaseResX.Name = "nudBaseResX"; + this.nudBaseResX.Size = new System.Drawing.Size(120, 22); + this.nudBaseResX.TabIndex = 13; + this.nudBaseResX.Value = new decimal(new int[] { + 1280, + 0, + 0, + 0}); + // + // lblBaseResY + // + this.lblBaseResY.AutoSize = true; + this.lblBaseResY.Location = new System.Drawing.Point(760, 178); + this.lblBaseResY.Name = "lblBaseResY"; + this.lblBaseResY.Size = new System.Drawing.Size(82, 16); + this.lblBaseResY.TabIndex = 14; + this.lblBaseResY.Text = "Base Res Y:"; + // + // nudBaseResY + // + this.nudBaseResY.Location = new System.Drawing.Point(860, 176); + this.nudBaseResY.Maximum = new decimal(new int[] { + 10000, + 0, + 0, + 0}); + this.nudBaseResY.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.nudBaseResY.Name = "nudBaseResY"; + this.nudBaseResY.Size = new System.Drawing.Size(120, 22); + this.nudBaseResY.TabIndex = 15; + this.nudBaseResY.Value = new decimal(new int[] { + 720, 0, 0, 0}); @@ -221,7 +319,7 @@ this.lblFontSize.Location = new System.Drawing.Point(24, 228); this.lblFontSize.Name = "lblFontSize"; this.lblFontSize.Size = new System.Drawing.Size(65, 16); - this.lblFontSize.TabIndex = 12; + this.lblFontSize.TabIndex = 16; this.lblFontSize.Text = "Font Size:"; // // nudFontSize @@ -239,7 +337,7 @@ 0}); this.nudFontSize.Name = "nudFontSize"; this.nudFontSize.Size = new System.Drawing.Size(120, 22); - this.nudFontSize.TabIndex = 13; + this.nudFontSize.TabIndex = 17; this.nudFontSize.Value = new decimal(new int[] { 16, 0, @@ -252,7 +350,7 @@ this.lblOffsetX.Location = new System.Drawing.Point(300, 228); this.lblOffsetX.Name = "lblOffsetX"; this.lblOffsetX.Size = new System.Drawing.Size(55, 16); - this.lblOffsetX.TabIndex = 14; + this.lblOffsetX.TabIndex = 18; this.lblOffsetX.Text = "Offset X:"; // // nudOffsetX @@ -265,43 +363,159 @@ 0}); this.nudOffsetX.Name = "nudOffsetX"; this.nudOffsetX.Size = new System.Drawing.Size(120, 22); - this.nudOffsetX.TabIndex = 15; + this.nudOffsetX.TabIndex = 19; this.nudOffsetX.Value = new decimal(new int[] { 4, 0, 0, 0}); // + // lblBottomOffset + // + this.lblBottomOffset.AutoSize = true; + this.lblBottomOffset.Location = new System.Drawing.Point(520, 228); + this.lblBottomOffset.Name = "lblBottomOffset"; + this.lblBottomOffset.Size = new System.Drawing.Size(89, 16); + this.lblBottomOffset.TabIndex = 20; + this.lblBottomOffset.Text = "Bottom Offset:"; + // + // nudBottomOffset + // + this.nudBottomOffset.Location = new System.Drawing.Point(620, 226); + this.nudBottomOffset.Maximum = new decimal(new int[] { + 1000, + 0, + 0, + 0}); + this.nudBottomOffset.Name = "nudBottomOffset"; + this.nudBottomOffset.Size = new System.Drawing.Size(120, 22); + this.nudBottomOffset.TabIndex = 21; + this.nudBottomOffset.Value = new decimal(new int[] { + 18, + 0, + 0, + 0}); + // + // lblSbsSideMargin + // + this.lblSbsSideMargin.AutoSize = true; + this.lblSbsSideMargin.Location = new System.Drawing.Point(24, 278); + this.lblSbsSideMargin.Name = "lblSbsSideMargin"; + this.lblSbsSideMargin.Size = new System.Drawing.Size(112, 16); + this.lblSbsSideMargin.TabIndex = 22; + this.lblSbsSideMargin.Text = "SBS Side Margin:"; + // + // nudSbsSideMargin + // + this.nudSbsSideMargin.Location = new System.Drawing.Point(140, 276); + this.nudSbsSideMargin.Maximum = new decimal(new int[] { + 5000, + 0, + 0, + 0}); + this.nudSbsSideMargin.Name = "nudSbsSideMargin"; + this.nudSbsSideMargin.Size = new System.Drawing.Size(120, 22); + this.nudSbsSideMargin.TabIndex = 23; + this.nudSbsSideMargin.Value = new decimal(new int[] { + 192, + 0, + 0, + 0}); + // + // lblOuTopMargin + // + this.lblOuTopMargin.AutoSize = true; + this.lblOuTopMargin.Location = new System.Drawing.Point(300, 278); + this.lblOuTopMargin.Name = "lblOuTopMargin"; + this.lblOuTopMargin.Size = new System.Drawing.Size(102, 16); + this.lblOuTopMargin.TabIndex = 24; + this.lblOuTopMargin.Text = "OU Top Margin:"; + // + // nudOuTopMargin + // + this.nudOuTopMargin.Location = new System.Drawing.Point(410, 276); + this.nudOuTopMargin.Maximum = new decimal(new int[] { + 5000, + 0, + 0, + 0}); + this.nudOuTopMargin.Name = "nudOuTopMargin"; + this.nudOuTopMargin.Size = new System.Drawing.Size(120, 22); + this.nudOuTopMargin.TabIndex = 25; + this.nudOuTopMargin.Value = new decimal(new int[] { + 154, + 0, + 0, + 0}); + // + // lblVerticalMargin + // + this.lblVerticalMargin.AutoSize = true; + this.lblVerticalMargin.Location = new System.Drawing.Point(560, 278); + this.lblVerticalMargin.Name = "lblVerticalMargin"; + this.lblVerticalMargin.Size = new System.Drawing.Size(99, 16); + this.lblVerticalMargin.TabIndex = 26; + this.lblVerticalMargin.Text = "Vertical Margin:"; + // + // nudVerticalMargin + // + this.nudVerticalMargin.Location = new System.Drawing.Point(670, 276); + this.nudVerticalMargin.Maximum = new decimal(new int[] { + 5000, + 0, + 0, + 0}); + this.nudVerticalMargin.Name = "nudVerticalMargin"; + this.nudVerticalMargin.Size = new System.Drawing.Size(120, 22); + this.nudVerticalMargin.TabIndex = 27; + this.nudVerticalMargin.Value = new decimal(new int[] { + 10, + 0, + 0, + 0}); + // // btnConvert // - this.btnConvert.Location = new System.Drawing.Point(27, 283); + this.btnConvert.Location = new System.Drawing.Point(27, 329); this.btnConvert.Name = "btnConvert"; this.btnConvert.Size = new System.Drawing.Size(145, 40); - this.btnConvert.TabIndex = 16; + this.btnConvert.TabIndex = 28; this.btnConvert.Text = "Convert"; this.btnConvert.UseVisualStyleBackColor = true; this.btnConvert.Click += new System.EventHandler(this.btnConvert_Click); // // txtStatus // - this.txtStatus.Location = new System.Drawing.Point(27, 349); + this.txtStatus.Location = new System.Drawing.Point(27, 392); this.txtStatus.Multiline = true; this.txtStatus.Name = "txtStatus"; this.txtStatus.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.txtStatus.Size = new System.Drawing.Size(1033, 225); - this.txtStatus.TabIndex = 17; + this.txtStatus.TabIndex = 29; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1088, 609); + this.ClientSize = new System.Drawing.Size(1088, 640); this.Controls.Add(this.txtStatus); this.Controls.Add(this.btnConvert); + this.Controls.Add(this.nudVerticalMargin); + this.Controls.Add(this.lblVerticalMargin); + this.Controls.Add(this.nudOuTopMargin); + this.Controls.Add(this.lblOuTopMargin); + this.Controls.Add(this.nudSbsSideMargin); + this.Controls.Add(this.lblSbsSideMargin); + this.Controls.Add(this.nudBottomOffset); + this.Controls.Add(this.lblBottomOffset); this.Controls.Add(this.nudOffsetX); this.Controls.Add(this.lblOffsetX); this.Controls.Add(this.nudFontSize); this.Controls.Add(this.lblFontSize); + this.Controls.Add(this.nudBaseResY); + this.Controls.Add(this.lblBaseResY); + this.Controls.Add(this.nudBaseResX); + this.Controls.Add(this.lblBaseResX); this.Controls.Add(this.nudResY); this.Controls.Add(this.lblResY); this.Controls.Add(this.nudResX); @@ -316,10 +530,17 @@ this.Controls.Add(this.lblInputFile); this.Name = "Form1"; this.Text = "Convert SRT to 3D ASS"; + this.Load += new System.EventHandler(this.Form1_Load); ((System.ComponentModel.ISupportInitialize)(this.nudResX)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.nudResY)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudBaseResX)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudBaseResY)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.nudFontSize)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.nudOffsetX)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudBottomOffset)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudSbsSideMargin)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudOuTopMargin)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudVerticalMargin)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); diff --git a/ConvertSRTto3DASSGUI/Form1.cs b/ConvertSRTto3DASSGUI/Form1.cs index 5550cf3..e909b0c 100644 --- a/ConvertSRTto3DASSGUI/Form1.cs +++ b/ConvertSRTto3DASSGUI/Form1.cs @@ -1,15 +1,29 @@ -using System; +using ConvertSRTto3DASS; +using System; using System.IO; using System.Windows.Forms; -using ConvertSRTto3DASS; +using static ConvertSRTto3DASS.Converter; namespace ConvertSRTto3DASSGUI { public partial class Form1 : Form { + // Keep these in sync with Converter.cs defaults + private const int DefaultResX = Converter.ConverterDefaults.ResX;//1280 + private const int DefaultResY = 720; + private const int DefaultBaseResX = 1280; + private const int DefaultBaseResY = 720; + private const int DefaultFontSize = 16; + private const int DefaultOffsetX = 4; + private const int DefaultBottomOffset = 18; + private const int DefaultSbsSideMargin = 192; + private const int DefaultOuTopMargin = 154; + private const int DefaultVerticalMargin = 10; + public Form1() { InitializeComponent(); + InitializeDefaults(); if (cmbMode.Items.Count > 0) cmbMode.SelectedIndex = 0; @@ -17,6 +31,39 @@ namespace ConvertSRTto3DASSGUI UpdateModeUI(); } + private void InitializeDefaults() + { + txtInputFile.Text = string.Empty; + txtOutputFile.Text = string.Empty; + + nudResX.Value = ConverterDefaults.ResX; + nudResY.Value = ConverterDefaults.ResY; + nudBaseResX.Value = ConverterDefaults.BaseResX; + nudBaseResY.Value = ConverterDefaults.BaseResY; + nudFontSize.Value = ConverterDefaults.FontSize; + nudOffsetX.Value = ConverterDefaults.OffsetX; + nudBottomOffset.Value = ConverterDefaults.BottomOffset; + nudSbsSideMargin.Value = ConverterDefaults.SbsSideMargin; + nudOuTopMargin.Value = ConverterDefaults.OuTopMargin; + nudVerticalMargin.Value = ConverterDefaults.VerticalMargin; + + switch (ConverterDefaults.DefaultMode.ToLowerInvariant()) + { + case "sbs": + cmbMode.SelectedIndex = 0; + break; + case "ou": + cmbMode.SelectedIndex = 1; + break; + case "rg": + cmbMode.SelectedIndex = 2; + break; + default: + cmbMode.SelectedIndex = 0; + break; + } + } + private void btnBrowseInput_Click(object sender, EventArgs e) { using (var ofd = new OpenFileDialog()) @@ -84,7 +131,7 @@ namespace ConvertSRTto3DASSGUI string inputPath = txtInputFile.Text.Trim(); string outputPath = txtOutputFile.Text.Trim(); - string mode = cmbMode.SelectedItem?.ToString() ?? "sbs"; + string mode = GetSelectedModeValue(); if (string.IsNullOrWhiteSpace(inputPath)) { @@ -106,26 +153,43 @@ namespace ConvertSRTto3DASSGUI int resX = (int)nudResX.Value; int resY = (int)nudResY.Value; + int baseResX = (int)nudBaseResX.Value; + int baseResY = (int)nudBaseResY.Value; int fontSize = (int)nudFontSize.Value; int offsetX = (int)nudOffsetX.Value; + int bottomOffset = (int)nudBottomOffset.Value; + int sbsSideMargin = (int)nudSbsSideMargin.Value; + int ouTopMargin = (int)nudOuTopMargin.Value; + int verticalMargin = (int)nudVerticalMargin.Value; AppendStatus("Starting conversion..."); AppendStatus("Input: " + inputPath); AppendStatus("Output: " + outputPath); AppendStatus("Mode: " + mode); AppendStatus("Resolution: " + resX + "x" + resY); + AppendStatus("Base Resolution: " + baseResX + "x" + baseResY); AppendStatus("Font Size: " + fontSize); AppendStatus("OffsetX: " + offsetX); + AppendStatus("BottomOffset: " + bottomOffset); + AppendStatus("SbsSideMargin: " + sbsSideMargin); + AppendStatus("OuTopMargin: " + ouTopMargin); + AppendStatus("VerticalMargin: " + verticalMargin); - ConvertSRTto3DASS.Converter.Main(new[] + Converter.Main(new[] { - txtInputFile.Text, - "--mode", GetSelectedModeValue(), - "--resx", nudResX.Value.ToString(), - "--resy", nudResY.Value.ToString(), - "--fontsize", nudFontSize.Value.ToString(), - "--offsetx", nudOffsetX.Value.ToString(), - "--output", txtOutputFile.Text + inputPath, + "--mode", mode, + "--resx", resX.ToString(), + "--resy", resY.ToString(), + "--baseresx", baseResX.ToString(), + "--baseresy", baseResY.ToString(), + "--fontsize", fontSize.ToString(), + "--offsetx", offsetX.ToString(), + "--bottomoffset", bottomOffset.ToString(), + "--sbssidemargin", sbsSideMargin.ToString(), + "--outopmargin", ouTopMargin.ToString(), + "--verticalmargin", verticalMargin.ToString(), + "--output", outputPath }); AppendStatus("Conversion complete."); @@ -140,11 +204,26 @@ namespace ConvertSRTto3DASSGUI private void UpdateModeUI() { - string mode = cmbMode.SelectedItem?.ToString() ?? "sbs"; - bool isRg = mode.Equals("rg", StringComparison.OrdinalIgnoreCase); + string mode = GetSelectedModeValue(); + + bool isSbs = mode == "sbs"; + bool isOu = mode == "ou"; + bool isRg = mode == "rg"; nudOffsetX.Enabled = isRg; lblOffsetX.Enabled = isRg; + + nudBottomOffset.Enabled = isRg; + lblBottomOffset.Enabled = isRg; + + nudSbsSideMargin.Enabled = isSbs; + lblSbsSideMargin.Enabled = isSbs; + + nudOuTopMargin.Enabled = isOu; + lblOuTopMargin.Enabled = isOu; + + nudVerticalMargin.Enabled = true; + lblVerticalMargin.Enabled = true; } private void AppendStatus(string message) @@ -154,5 +233,9 @@ namespace ConvertSRTto3DASSGUI txtStatus.AppendText(message); } + + private void Form1_Load(object sender, EventArgs e) + { + } } } \ No newline at end of file