This commit is contained in:
Nikolaj Olsson 2018-11-22 12:55:03 +01:00
commit 224d39c34a
52 changed files with 1554 additions and 508 deletions

View File

@ -16,7 +16,9 @@
* Make custom "Choose font" dialog - thx OmrSi
* Update Bing translator from V2 to V3 API
* Faster Tesseract OCR if CPU has many cores
* Try using word lists for uppercase i inside words - thx TeDDy
* Try using word lists for uppercase "i" inside words - thx TeDDy
* Improve unknown json importer - thx Thamy
* Improve paste in list view - thx OmrSi/darnn
* FIXED:
* Go back to Tesseract 3.02 (T4 available as in-program download)
* Fix Bing translator sign-up url - thx sopor
@ -32,7 +34,17 @@
* Fix "Set end, next start + go to next" w org sub - thx OmrSi
* Fix crash in Remove text for HI" - thx indeed-a-genius
* Fix "total seconds" in "Export custom format" - thx David
* Fix mpv crash/hang after open 4+ videos
* Add custom fade up/down for DCinema smpte - thx felagund
* Fix reading last line with zero duration - thx darnn
* Fix for column paste - thx OmrSi
* Fix adding music symbols with tags - thx
* Fix syntax coloring in "Fix common errors" - thx OmrSi
* Fix somtimes not updating total line length - thx OmrSi
* Fix text/image overlap in manual image to text OCR - thx amichaeltm
* Do not ignore words of combined letters/numbers - thx Boulder08
* Trying to fix mpv missing text refresh - thx darnn
* Fix crash in "add better multi match" - thx Boulder08
3.5.7 (9th August 2018)
* NEW:

View File

@ -1999,6 +1999,7 @@
If new word(s) and longer than 5 chars and exists in spelling dictionary, it is (or they are) accepted -->
<WordPart from="IVI" to="M" />
<WordPart from="/" to="l" />
<WordPart from="|" to="I" />
<WordPart from="vv" to="w" />
<WordPart from="m" to="rn" />
<WordPart from="l" to="i" />
@ -2302,6 +2303,14 @@
<LinePart from=" You ' re " to=" You're " />
<LinePart from=" that' s " to=" that's " />
<LinePart from="1 2th " to="12th " />
<LinePart from="-| " to="- I " />
<LinePart from=" | " to=" I " />
<LinePart from=" |." to=" I." />
<LinePart from="-1 am " to="- I had " />
<LinePart from="-1 had " to="- I had " />
<LinePart from="-1 think " to="- I think " />
<LinePart from="-1 tried " to="- I tried " />
<LinePart from="-1 was " to="- I was " />
</PartialLines>
<PartialLinesAlways>
<LinePart from="forbest act" to="for best act" />
@ -2422,6 +2431,9 @@
<Beginning from="He' s " to="He's " />
<Beginning from="She' s " to="She's " />
<Beginning from="O kay, " to="Okay, " />
<Beginning from="l didn't" to="I didn't" />
<Beginning from="l don't" to="I don't" />
<Beginning from="-1 " to="- I" />
</BeginLines>
<EndLines>
<Ending from=", sin" to=", sir." />
@ -2453,5 +2465,11 @@
<RegularExpressions>
<RegEx find="([a-z]) Won't " replaceWith="$1 won't " />
<RegEx find=" L([,\r\n :;!?]+)" replaceWith=" I$1" />
<RegEx find="^-1 (\p{L})" replaceWith="- I $1" />
<RegEx find="^-1t (\p{L})" replaceWith="- It $1" />
<RegEx find="^-_\.(\p{L})" replaceWith="- ...$1" />
<RegEx find="^_\.\.(\p{L})" replaceWith="...$1" />
<!-- <RegEx find="(\p{L}{2,})&quot;s " replaceWith="$1's " /> -->
</RegularExpressions>
</OCRFixReplaceList>

View File

@ -1864,6 +1864,7 @@ This file is generated/updated by Multi Translator
<name>Dudek</name>
<name>Dudley</name>
<name>Duffy</name>
<name>Dufresne</name>
<name>Duke</name>
<name>Dukes</name>
<name>Dulles</name>

View File

@ -1136,6 +1136,7 @@ Note: Do check free disk space.</WaveFileMalformed>
<MergeWithLineAfter>Merge with line after</MergeWithLineAfter>
<Normal>Normal (remove formatting)</Normal>
<Underline>Underline</Underline>
<Box>Box</Box>
<Color>Color...</Color>
<FontName>Font name...</FontName>
<Alignment>Alignment...</Alignment>
@ -2334,6 +2335,8 @@ Keep changes?</KeepChangesMessage>
<DiscardTitle>Discard changes made in OCR?</DiscardTitle>
<DiscardText>Do you want to discard changes made in current OCR session?</DiscardText>
<MinLineSplitHeight>Min. line height (split)</MinLineSplitHeight>
<FallbackToX>Fallback to {0}</FallbackToX>
<ImagePreProcessing>Image pre-processing...</ImagePreProcessing>
</VobSubOcr>
<VobSubOcrCharacter>
<Title>VobSub - Manual image to text</Title>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,3 +0,0 @@
tessedit_create_hocr 1
tessedit_pageseg_mode 1
hocr_font_info 0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -91,9 +91,8 @@ PUSHD "src\bin\Release"
IF EXIST "temp_zip" RD /S /Q "temp_zip"
IF NOT EXIST "temp_zip" MD "temp_zip"
IF NOT EXIST "temp_zip\Languages" MD "temp_zip\Languages"
IF NOT EXIST "temp_zip\Tesseract4" MD "temp_zip\Tesseract4"
IF NOT EXIST "temp_zip\Tesseract4\tessdata" MD "temp_zip\Tesseract4\tessdata"
IF NOT EXIST "temp_zip\Tesseract4\tessdata\configs" MD "temp_zip\Tesseract4\tessdata\configs"
IF NOT EXIST "temp_zip\Dictionaries" MD "temp_zip\Dictionaries"
IF NOT EXIST "temp_zip\Ocr" MD "temp_zip\Ocr"
COPY /Y /V "..\..\..\LICENSE.txt" "temp_zip\"
COPY /Y /V "..\..\..\Changelog.txt" "temp_zip\"
@ -101,10 +100,8 @@ COPY /Y /V "Hunspellx86.dll" "temp_zip\"
COPY /Y /V "Hunspellx64.dll" "temp_zip\"
COPY /Y /V "SubtitleEdit.exe" "temp_zip\"
COPY /Y /V "Languages\*.xml" "temp_zip\Languages\"
COPY /Y /V "..\..\..\Tesseract4\tesseract.exe" "temp_zip\Tesseract4\"
COPY /Y /V "..\..\..\Tesseract4\*.dll" "temp_zip\Tesseract4\"
COPY /Y /V "..\..\..\Tesseract4\tessdata\configs\hocr" "temp_zip\Tesseract4\tessdata\configs\"
COPY /Y /V "..\..\..\Tesseract4\tessdata\*.traineddata" "temp_zip\Tesseract4\tessdata\"
COPY /Y /V "..\..\..\Dictionaries\*.*" "temp_zip\Dictionaries\"
COPY /Y /V "..\..\..\Ocr\*.*" "temp_zip\Ocr\"
PUSHD "temp_zip"
START "" /B /WAIT "%SEVENZIP%" a -tzip -mx=9 "SE%VERSION%.zip" * >NUL

View File

@ -11,11 +11,13 @@ namespace Nikse.SubtitleEdit.Core.Forms.FixCommonErrors
int noOfFixes = 0;
for (int i = 0; i < subtitle.Paragraphs.Count; i++)
{
Paragraph p = subtitle.Paragraphs[i];
var p = subtitle.Paragraphs[i];
p.Text = FixDifferentQuotes(p.Text); //TODO: extract to own rule
if (Utilities.CountTagInText(p.Text, '"') == 1)
{
Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
var next = subtitle.GetParagraphOrDefault(i + 1);
if (next != null)
{
double betweenMilliseconds = next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds;
@ -27,7 +29,7 @@ namespace Nikse.SubtitleEdit.Core.Forms.FixCommonErrors
next = null; // seems to have valid quotes, so no spanning
}
Paragraph prev = subtitle.GetParagraphOrDefault(i - 1);
var prev = subtitle.GetParagraphOrDefault(i - 1);
if (prev != null)
{
double betweenMilliseconds = p.StartTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds;
@ -170,5 +172,20 @@ namespace Nikse.SubtitleEdit.Core.Forms.FixCommonErrors
callbacks.UpdateFixStatus(noOfFixes, fixAction, language.XMissingQuotesAdded);
}
private string FixDifferentQuotes(string text)
{
if (text.Contains("„"))
return text;
if (Utilities.CountTagInText(text, "\"") == 1 && Utilities.CountTagInText(text, "”") == 1)
{
return text.Replace("”", "\"");
}
if (Utilities.CountTagInText(text, "\"") == 1 && Utilities.CountTagInText(text, "“") == 1)
{
return text.Replace("“", "\"");
}
return text;
}
}
}

View File

@ -370,6 +370,8 @@ namespace Nikse.SubtitleEdit.Core
if (s.Contains("< "))
s = FixInvalidItalicTags(s);
s = s.Replace("<box>", string.Empty).Replace("</box>", string.Empty);
return RemoveCommonHtmlTags(s);
}

View File

@ -1644,6 +1644,7 @@ namespace Nikse.SubtitleEdit.Core
MergeWithLineAfter = "Merge with line after",
Normal = "Normal (remove formatting)",
Underline = "Underline",
Box = "Box",
Color = "Color...",
FontName = "Font name...",
Alignment = "Alignment...",
@ -2665,6 +2666,8 @@ Keep changes?",
DiscardTitle = "Discard changes made in OCR?",
DiscardText = "Do you want to discard changes made in current OCR session?",
MinLineSplitHeight = "Min. line height (split)",
FallbackToX = "Fallback to {0}",
ImagePreProcessing = "Image pre-processing..."
};
VobSubOcrCharacter = new LanguageStructure.VobSubOcrCharacter

View File

@ -3802,6 +3802,9 @@ namespace Nikse.SubtitleEdit.Core
case "Main/Menu/ContextMenu/Underline":
language.Main.Menu.ContextMenu.Underline = reader.Value;
break;
case "Main/Menu/ContextMenu/Box":
language.Main.Menu.ContextMenu.Box = reader.Value;
break;
case "Main/Menu/ContextMenu/Color":
language.Main.Menu.ContextMenu.Color = reader.Value;
break;
@ -6307,6 +6310,12 @@ namespace Nikse.SubtitleEdit.Core
case "VobSubOcr/MinLineSplitHeight":
language.VobSubOcr.MinLineSplitHeight = reader.Value;
break;
case "VobSubOcr/FallbackToX":
language.VobSubOcr.FallbackToX = reader.Value;
break;
case "VobSubOcr/ImagePreProcessing":
language.VobSubOcr.ImagePreProcessing = reader.Value;
break;
case "VobSubOcrCharacter/Title":
language.VobSubOcrCharacter.Title = reader.Value;
break;

View File

@ -1504,6 +1504,7 @@
public string MergeWithLineAfter { get; set; }
public string Normal { get; set; }
public string Underline { get; set; }
public string Box { get; set; }
public string Color { get; set; }
public string FontName { get; set; }
public string Alignment { get; set; }
@ -2541,6 +2542,8 @@
public string DiscardTitle { get; set; }
public string DiscardText { get; set; }
public string MinLineSplitHeight { get; set; }
public string FallbackToX { get; set; }
public string ImagePreProcessing { get; set; }
}
public class VobSubOcrCharacter

View File

@ -1129,6 +1129,27 @@ namespace Nikse.SubtitleEdit.Core
}
}
public void MakeTwoColor(int minRgb, Color background, Color foreground)
{
var bufferBackground = new byte[4];
bufferBackground[0] = background.B; // B
bufferBackground[1] = background.G; // G
bufferBackground[2] = background.R; // R
bufferBackground[3] = 255; // A
var bufferForeground = new byte[4];
bufferForeground[0] = foreground.B; // B
bufferForeground[1] = foreground.G; // G
bufferForeground[2] = foreground.R; // R
bufferForeground[3] = 255; // A
for (int i = 0; i < _bitmapData.Length; i += 4)
{
if (_bitmapData[i + 3] < 1 || _bitmapData[i + 0] + _bitmapData[i + 1] + _bitmapData[i + 2] < minRgb)
Buffer.BlockCopy(bufferBackground, 0, _bitmapData, i, 4);
else
Buffer.BlockCopy(bufferForeground, 0, _bitmapData, i, 4);
}
}
public void MakeVerticalLinePartTransparent(int xStart, int xEnd, int y)
{
if (xEnd > Width - 1)

View File

@ -86,6 +86,7 @@ namespace Nikse.SubtitleEdit.Core
public bool SpellCheckShowCompletedMessage { get; set; }
public bool OcrFixUseHardcodedRules { get; set; }
public int OcrBinaryImageCompareRgbThreshold { get; set; }
public int OcrTesseract4RgbThreshold { get; set; }
public string Interjections { get; set; }
public string MicrosoftBingApiId { get; set; }
public string MicrosoftTranslatorApiKey { get; set; }
@ -228,6 +229,7 @@ namespace Nikse.SubtitleEdit.Core
SpellCheckAutoChangeNames = true;
OcrFixUseHardcodedRules = true;
OcrBinaryImageCompareRgbThreshold = 270;
OcrTesseract4RgbThreshold = 200;
Interjections = "Ah;Ahem;Ahh;Ahhh;Ahhhh;Eh;Ehh;Ehhh;Hm;Hmm;Hmmm;Huh;Mm;Mmm;Mmmm;Phew;Gah;Oh;Ohh;Ohhh;Ow;Oww;Owww;Ugh;Ughh;Uh;Uhh;Uhhh;Whew";
MicrosoftBingApiId = "C2C2E9A508E6748F0494D68DFD92FAA1FF9B0BA4";
GoogleTranslateUrl = "translate.google.com";
@ -1923,6 +1925,9 @@ $HorzAlign = Center
subNode = node.SelectSingleNode("OcrBinaryImageCompareRgbThreshold");
if (subNode != null)
settings.Tools.OcrBinaryImageCompareRgbThreshold = Convert.ToInt32(subNode.InnerText);
subNode = node.SelectSingleNode("OcrTesseract4RgbThreshold");
if (subNode != null)
settings.Tools.OcrTesseract4RgbThreshold = Convert.ToInt32(subNode.InnerText);
subNode = node.SelectSingleNode("Interjections");
if (subNode != null)
settings.Tools.Interjections = subNode.InnerText;
@ -3607,6 +3612,7 @@ $HorzAlign = Center
textWriter.WriteElementString("SpellCheckShowCompletedMessage", settings.Tools.SpellCheckShowCompletedMessage.ToString());
textWriter.WriteElementString("OcrFixUseHardcodedRules", settings.Tools.OcrFixUseHardcodedRules.ToString());
textWriter.WriteElementString("OcrBinaryImageCompareRgbThreshold", settings.Tools.OcrBinaryImageCompareRgbThreshold.ToString(CultureInfo.InvariantCulture));
textWriter.WriteElementString("OcrTesseract4RgbThreshold", settings.Tools.OcrTesseract4RgbThreshold.ToString(CultureInfo.InvariantCulture));
textWriter.WriteElementString("Interjections", settings.Tools.Interjections);
textWriter.WriteElementString("MicrosoftBingApiId", settings.Tools.MicrosoftBingApiId);
textWriter.WriteElementString("MicrosoftTranslatorApiKey", settings.Tools.MicrosoftTranslatorApiKey);

View File

@ -179,6 +179,30 @@ namespace Nikse.SubtitleEdit.Core.SpellCheck
return s;
}
public string ReplaceAssTagsWithBlanks(string s)
{
int start = s.IndexOf("{\\", StringComparison.Ordinal);
int end = s.IndexOf('}');
if (start < 0 || end < 0 || end < start)
{
return s;
}
while (start >= 0)
{
end = s.IndexOf('}', start + 1);
if (end < start)
break;
int l = end - start + 1;
s = s.Remove(start, l).Insert(start, string.Empty.PadLeft(l));
end++;
if (end >= s.Length)
break;
start = s.IndexOf("{\\", end, StringComparison.Ordinal);
}
return s;
}
public bool IsWordInUserPhrases(int index, List<SpellCheckWord> words)
{
string current = words[index].Text;

View File

@ -365,6 +365,8 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
string italicsOff = encoding.GetString(new byte[] { 0x81 });
string underlineOn = encoding.GetString(new byte[] { 0x82 });
string underlineOff = encoding.GetString(new byte[] { 0x83 });
string boxingOn = encoding.GetString(new byte[] { 0x84 });
string boxingOff = encoding.GetString(new byte[] { 0x85 });
if (Utilities.CountTagInText(TextField, "<i>") == 1 && TextField.StartsWith("<i>") && TextField.EndsWith("</i>")) // italic on all lines
TextField = TextField.Replace(Environment.NewLine, Environment.NewLine + "<i>");
TextField = TextField.Replace("<i>", italicsOn);
@ -375,6 +377,10 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
TextField = TextField.Replace("<U>", underlineOn);
TextField = TextField.Replace("</u>", underlineOff);
TextField = TextField.Replace("</U>", underlineOff);
TextField = TextField.Replace("<box>", boxingOn);
TextField = TextField.Replace("<BOX>", boxingOn);
TextField = TextField.Replace("</box>", boxingOff);
TextField = TextField.Replace("</BOX>", boxingOff);
if (header.CharacterCodeTableNumber == "00")
{
TextField = TextField.Replace("©", encoding.GetString(new byte[] { 0xd3 }));
@ -683,7 +689,9 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
var text = p.Text.Trim(Utilities.NewLineChars);
if (text.StartsWith("{\\an7}", StringComparison.Ordinal) || text.StartsWith("{\\an8}", StringComparison.Ordinal) || text.StartsWith("{\\an9}", StringComparison.Ordinal))
{
tti.VerticalPosition = (byte)(1 + Configuration.Settings.SubtitleSettings.EbuStlMarginTop); // top (vertical)
tti.VerticalPosition = (byte)Configuration.Settings.SubtitleSettings.EbuStlMarginTop; // top (vertical)
if (header.DisplayStandardCode == "1" || header.DisplayStandardCode == "2") // teletext
tti.VerticalPosition++;
}
else if (text.StartsWith("{\\an4}", StringComparison.Ordinal) || text.StartsWith("{\\an5}", StringComparison.Ordinal) || text.StartsWith("{\\an6}", StringComparison.Ordinal))
{
@ -1222,6 +1230,8 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
const byte italicsOff = 0x81;
const byte underlineOn = 0x82;
const byte underlineOff = 0x83;
const byte boxingOn = 0x84;
const byte boxingOff = 0x85;
var list = new List<EbuTextTimingInformation>();
int index = startOfTextAndTimingBlock;
@ -1289,6 +1299,10 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
sb.Append("<u>");
else if (b == underlineOff && header.LanguageCode != LanguageCodeChinese)
sb.Append("</u>");
else if (b == boxingOn && header.LanguageCode != LanguageCodeChinese)
sb.Append("<box>");
else if (b == boxingOff && header.LanguageCode != LanguageCodeChinese)
sb.Append("</box>");
}
}
else if (b >= 0x86 && b <= 0x89) // Both - Reserved for future use

View File

@ -97,8 +97,10 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
ReadLine(subtitle, line, next, nextNext);
}
if (_paragraph != null && _paragraph.EndTime.TotalMilliseconds > _paragraph.StartTime.TotalMilliseconds)
if (_paragraph != null && _paragraph.ToString() != new Paragraph().ToString())
{
subtitle.Paragraphs.Add(_paragraph);
}
if (doRenum)
subtitle.Renumber();

View File

@ -29,7 +29,9 @@ namespace Nikse.SubtitleEdit.Core
if (subTcOnAloneLines.Paragraphs.Count > subtitle.Paragraphs.Count)
subtitle = subTcOnAloneLines;
if (subtitle.Paragraphs.Count < 2)
bool isJson = IsJson(lines);
if (subtitle.Paragraphs.Count < 2 && !isJson)
{
subtitle = ImportTimeCodesInFramesOnSameSeperateLine(lines);
if (subtitle.Paragraphs.Count < 2)
@ -59,7 +61,7 @@ namespace Nikse.SubtitleEdit.Core
CleanUp(subtitle);
}
if (subtitle.Paragraphs.Count < 2)
if (subtitle.Paragraphs.Count < 2 || isJson)
{
var jsonSubtitle = new UknownFormatImporterJson().AutoGuessImport(lines);
if (jsonSubtitle != null && jsonSubtitle.Paragraphs.Count > 2)
@ -79,6 +81,25 @@ namespace Nikse.SubtitleEdit.Core
return subtitle;
}
private bool IsJson(List<string> lines)
{
var jp = new JsonParser();
try
{
var sb = new StringBuilder();
foreach (var line in lines)
{
sb.AppendLine(line);
}
jp.Parse(sb.ToString());
return true;
}
catch
{
return false;
}
}
private static void CleanUp(Subtitle subtitle)
{
foreach (Paragraph p in subtitle.Paragraphs)

View File

@ -100,7 +100,12 @@ namespace Nikse.SubtitleEdit.Core
p.Style.Contains("\"startMillis\"") ||
p.Style.Contains("\"start_millis\"") ||
p.Style.Contains("\"startMilliseconds\"") ||
p.Style.Contains("\"start_millisecondsMs\""))
p.Style.Contains("\"start_millisecondsMs\"") ||
p.Style.Contains("\"fromMs\"") ||
p.Style.Contains("\"from_ms\"") ||
p.Style.Contains("\"fromMillis\"") ||
p.Style.Contains("\"fromMilliseconds\"") ||
p.Style.Contains("\"from_milliseconds\""))
{
msFound++;
}
@ -190,6 +195,7 @@ namespace Nikse.SubtitleEdit.Core
"startMillis", "start_Millis", "startmillis",
"startMs", "start_ms", "startms",
"startMilliseconds", "start_Millisesonds", "startmilliseconds",
"from", "fromTime", "from_ms", "fromMilliseconds", "from_milliseconds"
});
}
@ -202,6 +208,7 @@ namespace Nikse.SubtitleEdit.Core
"endMillis", "end_Millis", "endmillis",
"endMs", "end_ms", "startms",
"endMilliseconds", "end_Millisesonds", "endmilliseconds",
"to", "toTime", "to_ms", "toMilliseconds", "to_milliseconds"
});
}
@ -217,6 +224,8 @@ namespace Nikse.SubtitleEdit.Core
private static string ReadTextTag(string s)
{
var idx = s.IndexOf("\"text", StringComparison.OrdinalIgnoreCase);
if (idx < 0)
idx = s.IndexOf("\"content", StringComparison.OrdinalIgnoreCase);
if (idx < 0)
return null;
@ -226,9 +235,13 @@ namespace Nikse.SubtitleEdit.Core
s = s.Substring(0, idx + 1);
var text = Json.ReadTag(s, "text");
if (text == null)
text = Json.ReadTag(s, "content");
var textLines = Json.ReadArray(s, "text");
if (textLines == null || textLines.Count == 0)
textLines = Json.ReadArray(s, "content");
bool isArray = s.Contains("[");
if (isArray && textLines.Any(p => p == "end_time" || p == "endTime" || p == "end" || p == "endMs" || p == "endMilliseconds" || p == "end_ms"))
if (isArray && textLines.Any(p => p == "end_time" || p == "endTime" || p == "end" || p == "endMs" || p == "endMilliseconds" || p == "end_ms" || p == "to" || p == "to_ms" || p == "from" || p == "from_ms"))
isArray = false;
if (!isArray && !string.IsNullOrEmpty(text))
{

View File

@ -324,11 +324,13 @@ namespace Nikse.SubtitleEdit.Controls
SubtitleFormat format = new AdvancedSubStationAlpha();
if (subtitle.Header == null || !subtitle.Header.Contains("[V4+ Styles]"))
{
var oldSub = subtitle;
subtitle = new Subtitle(subtitle);
if (_subtitleTextBox.RightToLeft == RightToLeft.Yes && LanguageAutoDetect.CouldBeRightToLeftLanguge(subtitle))
{
foreach (var paragraph in subtitle.Paragraphs)
for (var index = 0; index < subtitle.Paragraphs.Count; index++)
{
var paragraph = subtitle.Paragraphs[index];
paragraph.Text = "\u200F" + paragraph.Text.Replace(Environment.NewLine, "\u200F" + Environment.NewLine + "\u200F") + "\u200F"; // RTL control character
}
}
@ -339,6 +341,21 @@ namespace Nikse.SubtitleEdit.Controls
subtitle.Header = AdvancedSubStationAlpha.DefaultHeader;
Configuration.Settings.SubtitleSettings.SsaFontSize = oldFontSize;
Configuration.Settings.SubtitleSettings.SsaFontBold = oldFontBold;
if (oldSub.Header != null && oldSub.Header.Length > 20 && oldSub.Header.Substring(3, 3) == "STL")
{
subtitle.Header = subtitle.Header.Replace("Style: Default,", "Style: Box,arial,20,&H00FFFFFF,&H0300FFFF,&H00000000,&H02000000,0,0,0,0,100,100,0,0,3,2,0,2,10,10,10,1" +
Environment.NewLine + "Style: Default,");
for (var index = 0; index < subtitle.Paragraphs.Count; index++)
{
var p = subtitle.Paragraphs[index];
if (p.Text.Contains("<box>"))
{
p.Extra = "Box";
p.Text = p.Text.Replace("<box>", string.Empty).Replace("</box>", string.Empty);
}
}
}
}
string text = subtitle.ToText(format);

View File

@ -1136,13 +1136,13 @@ namespace Nikse.SubtitleEdit.Forms
private void UpdateListSyntaxColoring()
{
if (Subtitle == null || Subtitle.Paragraphs.Count == 0 || _subtitleListViewIndex < 0 || _subtitleListViewIndex >= Subtitle.Paragraphs.Count)
if (FixedSubtitle == null || FixedSubtitle.Paragraphs.Count == 0 || _subtitleListViewIndex < 0 || _subtitleListViewIndex >= Subtitle.Paragraphs.Count)
return;
subtitleListView1.SyntaxColorLine(Subtitle.Paragraphs, _subtitleListViewIndex, Subtitle.Paragraphs[_subtitleListViewIndex]);
subtitleListView1.SyntaxColorLine(FixedSubtitle.Paragraphs, _subtitleListViewIndex, FixedSubtitle.Paragraphs[_subtitleListViewIndex]);
Paragraph next = Subtitle.GetParagraphOrDefault(_subtitleListViewIndex + 1);
if (next != null)
subtitleListView1.SyntaxColorLine(Subtitle.Paragraphs, _subtitleListViewIndex + 1, Subtitle.Paragraphs[_subtitleListViewIndex + 1]);
subtitleListView1.SyntaxColorLine(FixedSubtitle.Paragraphs, _subtitleListViewIndex + 1, FixedSubtitle.Paragraphs[_subtitleListViewIndex + 1]);
}
private void MaskedTextBox_TextChanged(object sender, EventArgs e)

View File

@ -38,9 +38,9 @@
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main));
Nikse.SubtitleEdit.Core.TimeCode timeCode4 = new Nikse.SubtitleEdit.Core.TimeCode();
Nikse.SubtitleEdit.Core.TimeCode timeCode5 = new Nikse.SubtitleEdit.Core.TimeCode();
Nikse.SubtitleEdit.Core.TimeCode timeCode6 = new Nikse.SubtitleEdit.Core.TimeCode();
Nikse.SubtitleEdit.Core.TimeCode timeCode1 = new Nikse.SubtitleEdit.Core.TimeCode();
Nikse.SubtitleEdit.Core.TimeCode timeCode2 = new Nikse.SubtitleEdit.Core.TimeCode();
Nikse.SubtitleEdit.Core.TimeCode timeCode3 = new Nikse.SubtitleEdit.Core.TimeCode();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.labelStatus = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripSelected = new System.Windows.Forms.ToolStripStatusLabel();
@ -288,6 +288,7 @@
this.normalToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.boldToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.italicToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.boxToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.underlineToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.colorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemFont = new System.Windows.Forms.ToolStripMenuItem();
@ -314,6 +315,7 @@
this.colorDialog1 = new System.Windows.Forms.ColorDialog();
this.groupBoxVideo = new System.Windows.Forms.GroupBox();
this.labelNextWord = new System.Windows.Forms.Label();
this.audioVisualizer = new Nikse.SubtitleEdit.Controls.AudioVisualizer();
this.checkBoxSyncListViewWithVideoWhilePlaying = new System.Windows.Forms.CheckBox();
this.labelVideoInfo = new System.Windows.Forms.Label();
this.trackBarWaveformPosition = new System.Windows.Forms.TrackBar();
@ -349,6 +351,7 @@
this.buttonPlayCurrent = new System.Windows.Forms.Button();
this.buttonPlayNext = new System.Windows.Forms.Button();
this.tabPageCreate = new System.Windows.Forms.TabPage();
this.timeUpDownVideoPosition = new Nikse.SubtitleEdit.Controls.TimeUpDown();
this.buttonGotoSub = new System.Windows.Forms.Button();
this.buttonBeforeText = new System.Windows.Forms.Button();
this.buttonSetEnd = new System.Windows.Forms.Button();
@ -383,6 +386,7 @@
this.labelVideoPosition2 = new System.Windows.Forms.Label();
this.buttonAdjustGoToPosAndPause = new System.Windows.Forms.Button();
this.buttonAdjustPlayBefore = new System.Windows.Forms.Button();
this.timeUpDownVideoPositionAdjust = new Nikse.SubtitleEdit.Controls.TimeUpDown();
this.ShowSubtitleTimer = new System.Windows.Forms.Timer(this.components);
this.timerAutoDuration = new System.Windows.Forms.Timer(this.components);
this.timerAutoContinue = new System.Windows.Forms.Timer(this.components);
@ -413,6 +417,7 @@
this.tabControlSubtitle = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.splitContainerListViewAndText = new System.Windows.Forms.SplitContainer();
this.SubtitleListview1 = new Nikse.SubtitleEdit.Controls.SubtitleListView();
this.groupBoxEdit = new System.Windows.Forms.GroupBox();
this.labelSingleLine = new System.Windows.Forms.Label();
this.labelAlternateSingleLine = new System.Windows.Forms.Label();
@ -424,6 +429,7 @@
this.labelTextAlternateLineLengths = new System.Windows.Forms.Label();
this.labelAlternateText = new System.Windows.Forms.Label();
this.labelText = new System.Windows.Forms.Label();
this.textBoxListViewTextAlternate = new Nikse.SubtitleEdit.Controls.SETextBox();
this.contextMenuStripTextBoxListView = new System.Windows.Forms.ContextMenuStrip(this.components);
this.toolStripMenuItemWebVttVoice = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparatorWebVTT = new System.Windows.Forms.ToolStripSeparator();
@ -458,28 +464,23 @@
this.labelTextLineTotal = new System.Windows.Forms.Label();
this.labelCharactersPerSecond = new System.Windows.Forms.Label();
this.buttonUnBreak = new System.Windows.Forms.Button();
this.timeUpDownStartTime = new Nikse.SubtitleEdit.Controls.TimeUpDown();
this.numericUpDownDuration = new System.Windows.Forms.NumericUpDown();
this.buttonPrevious = new System.Windows.Forms.Button();
this.buttonNext = new System.Windows.Forms.Button();
this.labelStartTime = new System.Windows.Forms.Label();
this.textBoxListViewText = new Nikse.SubtitleEdit.Controls.SETextBox();
this.labelDuration = new System.Windows.Forms.Label();
this.labelAutoDuration = new System.Windows.Forms.Label();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.textBoxSource = new System.Windows.Forms.TextBox();
this.panelVideoPlayer = new System.Windows.Forms.Panel();
this.mediaPlayer = new Nikse.SubtitleEdit.Controls.VideoPlayerContainer();
this.contextMenuStripEmpty = new System.Windows.Forms.ContextMenuStrip(this.components);
this.insertLineToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.imageListPlayRate = new System.Windows.Forms.ImageList(this.components);
this.timerTextUndo = new System.Windows.Forms.Timer(this.components);
this.timerAlternateTextUndo = new System.Windows.Forms.Timer(this.components);
this.SubtitleListview1 = new Nikse.SubtitleEdit.Controls.SubtitleListView();
this.textBoxListViewTextAlternate = new Nikse.SubtitleEdit.Controls.SETextBox();
this.timeUpDownStartTime = new Nikse.SubtitleEdit.Controls.TimeUpDown();
this.textBoxListViewText = new Nikse.SubtitleEdit.Controls.SETextBox();
this.mediaPlayer = new Nikse.SubtitleEdit.Controls.VideoPlayerContainer();
this.audioVisualizer = new Nikse.SubtitleEdit.Controls.AudioVisualizer();
this.timeUpDownVideoPosition = new Nikse.SubtitleEdit.Controls.TimeUpDown();
this.timeUpDownVideoPositionAdjust = new Nikse.SubtitleEdit.Controls.TimeUpDown();
this.statusStrip1.SuspendLayout();
this.toolStrip1.SuspendLayout();
this.menuStrip1.SuspendLayout();
@ -2379,6 +2380,7 @@
this.normalToolStripMenuItem,
this.boldToolStripMenuItem,
this.italicToolStripMenuItem,
this.boxToolStripMenuItem,
this.underlineToolStripMenuItem,
this.colorToolStripMenuItem,
this.toolStripMenuItemFont,
@ -2400,7 +2402,7 @@
this.changeCasingForSelectedLinesToolStripMenuItem,
this.toolStripMenuItemSaveSelectedLines});
this.contextMenuStripListview.Name = "contextMenuStripListview";
this.contextMenuStripListview.Size = new System.Drawing.Size(285, 848);
this.contextMenuStripListview.Size = new System.Drawing.Size(285, 892);
this.contextMenuStripListview.Closed += new System.Windows.Forms.ToolStripDropDownClosedEventHandler(this.MenuClosed);
this.contextMenuStripListview.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuStripListviewOpening);
this.contextMenuStripListview.Opened += new System.EventHandler(this.MenuOpened);
@ -2626,6 +2628,13 @@
this.italicToolStripMenuItem.Text = "Italic";
this.italicToolStripMenuItem.Click += new System.EventHandler(this.ItalicToolStripMenuItemClick);
//
// boxToolStripMenuItem
//
this.boxToolStripMenuItem.Name = "boxToolStripMenuItem";
this.boxToolStripMenuItem.Size = new System.Drawing.Size(284, 22);
this.boxToolStripMenuItem.Text = "Box";
this.boxToolStripMenuItem.Click += new System.EventHandler(this.boxToolStripMenuItem_Click);
//
// underlineToolStripMenuItem
//
this.underlineToolStripMenuItem.Name = "underlineToolStripMenuItem";
@ -2799,6 +2808,44 @@
this.labelNextWord.Text = "Next: xxx";
this.labelNextWord.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// audioVisualizer
//
this.audioVisualizer.AllowDrop = true;
this.audioVisualizer.AllowNewSelection = true;
this.audioVisualizer.AllowOverlap = false;
this.audioVisualizer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.audioVisualizer.BackColor = System.Drawing.Color.Black;
this.audioVisualizer.BackgroundColor = System.Drawing.Color.Black;
this.audioVisualizer.Color = System.Drawing.Color.GreenYellow;
this.audioVisualizer.Font = new System.Drawing.Font("Segoe UI", 9F);
this.audioVisualizer.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(18)))));
this.audioVisualizer.Location = new System.Drawing.Point(472, 32);
this.audioVisualizer.Margin = new System.Windows.Forms.Padding(0);
this.audioVisualizer.Name = "audioVisualizer";
this.audioVisualizer.NewSelectionParagraph = null;
this.audioVisualizer.ParagraphColor = System.Drawing.Color.LimeGreen;
this.audioVisualizer.SceneChanges = ((System.Collections.Generic.List<double>)(resources.GetObject("audioVisualizer.SceneChanges")));
this.audioVisualizer.SelectedColor = System.Drawing.Color.Red;
this.audioVisualizer.ShowGridLines = true;
this.audioVisualizer.ShowSpectrogram = false;
this.audioVisualizer.ShowWaveform = true;
this.audioVisualizer.Size = new System.Drawing.Size(499, 229);
this.audioVisualizer.StartPositionSeconds = 0D;
this.audioVisualizer.TabIndex = 6;
this.audioVisualizer.TextBold = true;
this.audioVisualizer.TextColor = System.Drawing.Color.Gray;
this.audioVisualizer.TextSize = 9F;
this.audioVisualizer.VerticalZoomFactor = 1D;
this.audioVisualizer.WaveformNotLoadedText = "Click to add waveform";
this.audioVisualizer.WavePeaks = null;
this.audioVisualizer.ZoomFactor = 1D;
this.audioVisualizer.Click += new System.EventHandler(this.AudioWaveform_Click);
this.audioVisualizer.DragDrop += new System.Windows.Forms.DragEventHandler(this.AudioWaveformDragDrop);
this.audioVisualizer.DragEnter += new System.Windows.Forms.DragEventHandler(this.AudioWaveformDragEnter);
this.audioVisualizer.MouseEnter += new System.EventHandler(this.audioVisualizer_MouseEnter);
//
// checkBoxSyncListViewWithVideoWhilePlaying
//
this.checkBoxSyncListViewWithVideoWhilePlaying.AutoSize = true;
@ -3223,6 +3270,26 @@
this.tabPageCreate.Text = "Create";
this.tabPageCreate.UseVisualStyleBackColor = true;
//
// timeUpDownVideoPosition
//
this.timeUpDownVideoPosition.AutoSize = true;
this.timeUpDownVideoPosition.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.timeUpDownVideoPosition.Font = new System.Drawing.Font("Segoe UI", 9F);
this.timeUpDownVideoPosition.Location = new System.Drawing.Point(96, 191);
this.timeUpDownVideoPosition.Margin = new System.Windows.Forms.Padding(4);
this.timeUpDownVideoPosition.Name = "timeUpDownVideoPosition";
this.timeUpDownVideoPosition.Size = new System.Drawing.Size(96, 27);
this.timeUpDownVideoPosition.TabIndex = 12;
timeCode1.Hours = 0;
timeCode1.Milliseconds = 0;
timeCode1.Minutes = 0;
timeCode1.Seconds = 0;
timeCode1.TimeSpan = System.TimeSpan.Parse("00:00:00");
timeCode1.TotalMilliseconds = 0D;
timeCode1.TotalSeconds = 0D;
this.timeUpDownVideoPosition.TimeCode = timeCode1;
this.timeUpDownVideoPosition.UseVideoOffset = false;
//
// buttonGotoSub
//
this.buttonGotoSub.Location = new System.Drawing.Point(6, 58);
@ -3636,6 +3703,26 @@
this.buttonAdjustPlayBefore.UseVisualStyleBackColor = true;
this.buttonAdjustPlayBefore.Click += new System.EventHandler(this.buttonBeforeText_Click);
//
// timeUpDownVideoPositionAdjust
//
this.timeUpDownVideoPositionAdjust.AutoSize = true;
this.timeUpDownVideoPositionAdjust.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.timeUpDownVideoPositionAdjust.Font = new System.Drawing.Font("Segoe UI", 9F);
this.timeUpDownVideoPositionAdjust.Location = new System.Drawing.Point(96, 213);
this.timeUpDownVideoPositionAdjust.Margin = new System.Windows.Forms.Padding(4);
this.timeUpDownVideoPositionAdjust.Name = "timeUpDownVideoPositionAdjust";
this.timeUpDownVideoPositionAdjust.Size = new System.Drawing.Size(96, 27);
this.timeUpDownVideoPositionAdjust.TabIndex = 13;
timeCode2.Hours = 0;
timeCode2.Milliseconds = 0;
timeCode2.Minutes = 0;
timeCode2.Seconds = 0;
timeCode2.TimeSpan = System.TimeSpan.Parse("00:00:00");
timeCode2.TotalMilliseconds = 0D;
timeCode2.TotalSeconds = 0D;
this.timeUpDownVideoPositionAdjust.TimeCode = timeCode2;
this.timeUpDownVideoPositionAdjust.UseVideoOffset = false;
//
// ShowSubtitleTimer
//
this.ShowSubtitleTimer.Enabled = true;
@ -3900,6 +3987,36 @@
this.splitContainerListViewAndText.SplitterDistance = 91;
this.splitContainerListViewAndText.TabIndex = 2;
//
// SubtitleListview1
//
this.SubtitleListview1.AllowColumnReorder = true;
this.SubtitleListview1.AllowDrop = true;
this.SubtitleListview1.ContextMenuStrip = this.contextMenuStripListview;
this.SubtitleListview1.Dock = System.Windows.Forms.DockStyle.Fill;
this.SubtitleListview1.FirstVisibleIndex = -1;
this.SubtitleListview1.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.SubtitleListview1.FullRowSelect = true;
this.SubtitleListview1.GridLines = true;
this.SubtitleListview1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.SubtitleListview1.HideSelection = false;
this.SubtitleListview1.Location = new System.Drawing.Point(0, 0);
this.SubtitleListview1.Name = "SubtitleListview1";
this.SubtitleListview1.OwnerDraw = true;
this.SubtitleListview1.Size = new System.Drawing.Size(724, 91);
this.SubtitleListview1.SubtitleFontBold = false;
this.SubtitleListview1.SubtitleFontName = "Tahoma";
this.SubtitleListview1.SubtitleFontSize = 8;
this.SubtitleListview1.TabIndex = 0;
this.SubtitleListview1.UseCompatibleStateImageBehavior = false;
this.SubtitleListview1.UseSyntaxColoring = true;
this.SubtitleListview1.View = System.Windows.Forms.View.Details;
this.SubtitleListview1.SelectedIndexChanged += new System.EventHandler(this.SubtitleListview1_SelectedIndexChanged);
this.SubtitleListview1.DragDrop += new System.Windows.Forms.DragEventHandler(this.SubtitleListview1_DragDrop);
this.SubtitleListview1.DragEnter += new System.Windows.Forms.DragEventHandler(this.SubtitleListview1_DragEnter);
this.SubtitleListview1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.SubtitleListview1KeyDown);
this.SubtitleListview1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.SubtitleListview1_MouseDoubleClick);
this.SubtitleListview1.MouseEnter += new System.EventHandler(this.SubtitleListview1_MouseEnter);
//
// groupBoxEdit
//
this.groupBoxEdit.Controls.Add(this.labelSingleLine);
@ -4035,6 +4152,28 @@
this.labelText.TabIndex = 5;
this.labelText.Text = "Text";
//
// textBoxListViewTextAlternate
//
this.textBoxListViewTextAlternate.AllowDrop = true;
this.textBoxListViewTextAlternate.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxListViewTextAlternate.ContextMenuStrip = this.contextMenuStripTextBoxListView;
this.textBoxListViewTextAlternate.Enabled = false;
this.textBoxListViewTextAlternate.HideSelection = false;
this.textBoxListViewTextAlternate.Location = new System.Drawing.Point(946, 28);
this.textBoxListViewTextAlternate.Multiline = true;
this.textBoxListViewTextAlternate.Name = "textBoxListViewTextAlternate";
this.textBoxListViewTextAlternate.Size = new System.Drawing.Size(0, 63);
this.textBoxListViewTextAlternate.TabIndex = 33;
this.textBoxListViewTextAlternate.Visible = false;
this.textBoxListViewTextAlternate.MouseClick += new System.Windows.Forms.MouseEventHandler(this.TextBoxListViewTextAlternateMouseClick);
this.textBoxListViewTextAlternate.TextChanged += new System.EventHandler(this.textBoxListViewTextAlternate_TextChanged);
this.textBoxListViewTextAlternate.Enter += new System.EventHandler(this.TextBoxListViewTextAlternateEnter);
this.textBoxListViewTextAlternate.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxListViewTextAlternateKeyDown);
this.textBoxListViewTextAlternate.KeyUp += new System.Windows.Forms.KeyEventHandler(this.TextBoxListViewTextAlternateKeyUp);
this.textBoxListViewTextAlternate.MouseMove += new System.Windows.Forms.MouseEventHandler(this.TextBoxListViewTextAlternateMouseMove);
//
// contextMenuStripTextBoxListView
//
this.contextMenuStripTextBoxListView.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -4315,6 +4454,26 @@
this.buttonUnBreak.UseVisualStyleBackColor = true;
this.buttonUnBreak.Click += new System.EventHandler(this.ButtonUnBreakClick);
//
// timeUpDownStartTime
//
this.timeUpDownStartTime.AutoSize = true;
this.timeUpDownStartTime.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.timeUpDownStartTime.Font = new System.Drawing.Font("Segoe UI", 9F);
this.timeUpDownStartTime.Location = new System.Drawing.Point(9, 26);
this.timeUpDownStartTime.Margin = new System.Windows.Forms.Padding(4);
this.timeUpDownStartTime.Name = "timeUpDownStartTime";
this.timeUpDownStartTime.Size = new System.Drawing.Size(96, 27);
this.timeUpDownStartTime.TabIndex = 0;
timeCode3.Hours = 0;
timeCode3.Milliseconds = 0;
timeCode3.Minutes = 0;
timeCode3.Seconds = 0;
timeCode3.TimeSpan = System.TimeSpan.Parse("00:00:00");
timeCode3.TotalMilliseconds = 0D;
timeCode3.TotalSeconds = 0D;
this.timeUpDownStartTime.TimeCode = timeCode3;
this.timeUpDownStartTime.UseVideoOffset = false;
//
// numericUpDownDuration
//
this.numericUpDownDuration.DecimalPlaces = 3;
@ -4368,6 +4527,28 @@
this.labelStartTime.TabIndex = 3;
this.labelStartTime.Text = "Start time";
//
// textBoxListViewText
//
this.textBoxListViewText.AllowDrop = true;
this.textBoxListViewText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxListViewText.ContextMenuStrip = this.contextMenuStripTextBoxListView;
this.textBoxListViewText.Enabled = false;
this.textBoxListViewText.HideSelection = false;
this.textBoxListViewText.Location = new System.Drawing.Point(236, 28);
this.textBoxListViewText.Multiline = true;
this.textBoxListViewText.Name = "textBoxListViewText";
this.textBoxListViewText.Size = new System.Drawing.Size(362, 63);
this.textBoxListViewText.TabIndex = 5;
this.textBoxListViewText.MouseClick += new System.Windows.Forms.MouseEventHandler(this.TextBoxListViewTextMouseClick);
this.textBoxListViewText.TextChanged += new System.EventHandler(this.TextBoxListViewTextTextChanged);
this.textBoxListViewText.Enter += new System.EventHandler(this.TextBoxListViewTextEnter);
this.textBoxListViewText.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxListViewTextKeyDown);
this.textBoxListViewText.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textBoxListViewText_KeyUp);
this.textBoxListViewText.Leave += new System.EventHandler(this.textBoxListViewText_Leave);
this.textBoxListViewText.MouseMove += new System.Windows.Forms.MouseEventHandler(this.textBoxListViewText_MouseMove);
//
// labelDuration
//
this.labelDuration.AutoSize = true;
@ -4429,6 +4610,34 @@
this.panelVideoPlayer.Size = new System.Drawing.Size(220, 246);
this.panelVideoPlayer.TabIndex = 5;
//
// mediaPlayer
//
this.mediaPlayer.AllowDrop = true;
this.mediaPlayer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.mediaPlayer.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18)))));
this.mediaPlayer.CurrentPosition = 0D;
this.mediaPlayer.FontSizeFactor = 1F;
this.mediaPlayer.LastParagraph = null;
this.mediaPlayer.Location = new System.Drawing.Point(0, 0);
this.mediaPlayer.Margin = new System.Windows.Forms.Padding(0);
this.mediaPlayer.Name = "mediaPlayer";
this.mediaPlayer.ShowFullscreenButton = true;
this.mediaPlayer.ShowMuteButton = true;
this.mediaPlayer.ShowStopButton = true;
this.mediaPlayer.Size = new System.Drawing.Size(219, 246);
this.mediaPlayer.SmpteMode = false;
this.mediaPlayer.SubtitleText = "";
this.mediaPlayer.TabIndex = 5;
this.mediaPlayer.TextRightToLeft = System.Windows.Forms.RightToLeft.No;
this.mediaPlayer.VideoHeight = 0;
this.mediaPlayer.VideoPlayer = null;
this.mediaPlayer.VideoWidth = 0;
this.mediaPlayer.Volume = 0D;
this.mediaPlayer.DragDrop += new System.Windows.Forms.DragEventHandler(this.mediaPlayer_DragDrop);
this.mediaPlayer.DragEnter += new System.Windows.Forms.DragEventHandler(this.mediaPlayer_DragEnter);
//
// contextMenuStripEmpty
//
this.contextMenuStripEmpty.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -4460,206 +4669,6 @@
this.timerAlternateTextUndo.Interval = 700;
this.timerAlternateTextUndo.Tick += new System.EventHandler(this.TimerAlternateTextUndoTick);
//
// SubtitleListview1
//
this.SubtitleListview1.AllowColumnReorder = true;
this.SubtitleListview1.AllowDrop = true;
this.SubtitleListview1.ContextMenuStrip = this.contextMenuStripListview;
this.SubtitleListview1.Dock = System.Windows.Forms.DockStyle.Fill;
this.SubtitleListview1.FirstVisibleIndex = -1;
this.SubtitleListview1.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.SubtitleListview1.FullRowSelect = true;
this.SubtitleListview1.GridLines = true;
this.SubtitleListview1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.SubtitleListview1.HideSelection = false;
this.SubtitleListview1.Location = new System.Drawing.Point(0, 0);
this.SubtitleListview1.Name = "SubtitleListview1";
this.SubtitleListview1.OwnerDraw = true;
this.SubtitleListview1.Size = new System.Drawing.Size(724, 91);
this.SubtitleListview1.SubtitleFontBold = false;
this.SubtitleListview1.SubtitleFontName = "Tahoma";
this.SubtitleListview1.SubtitleFontSize = 8;
this.SubtitleListview1.TabIndex = 0;
this.SubtitleListview1.UseCompatibleStateImageBehavior = false;
this.SubtitleListview1.UseSyntaxColoring = true;
this.SubtitleListview1.View = System.Windows.Forms.View.Details;
this.SubtitleListview1.SelectedIndexChanged += new System.EventHandler(this.SubtitleListview1_SelectedIndexChanged);
this.SubtitleListview1.DragDrop += new System.Windows.Forms.DragEventHandler(this.SubtitleListview1_DragDrop);
this.SubtitleListview1.DragEnter += new System.Windows.Forms.DragEventHandler(this.SubtitleListview1_DragEnter);
this.SubtitleListview1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.SubtitleListview1KeyDown);
this.SubtitleListview1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.SubtitleListview1_MouseDoubleClick);
this.SubtitleListview1.MouseEnter += new System.EventHandler(this.SubtitleListview1_MouseEnter);
//
// textBoxListViewTextAlternate
//
this.textBoxListViewTextAlternate.AllowDrop = true;
this.textBoxListViewTextAlternate.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxListViewTextAlternate.ContextMenuStrip = this.contextMenuStripTextBoxListView;
this.textBoxListViewTextAlternate.Enabled = false;
this.textBoxListViewTextAlternate.HideSelection = false;
this.textBoxListViewTextAlternate.Location = new System.Drawing.Point(946, 28);
this.textBoxListViewTextAlternate.Multiline = true;
this.textBoxListViewTextAlternate.Name = "textBoxListViewTextAlternate";
this.textBoxListViewTextAlternate.Size = new System.Drawing.Size(0, 63);
this.textBoxListViewTextAlternate.TabIndex = 33;
this.textBoxListViewTextAlternate.Visible = false;
this.textBoxListViewTextAlternate.MouseClick += new System.Windows.Forms.MouseEventHandler(this.TextBoxListViewTextAlternateMouseClick);
this.textBoxListViewTextAlternate.TextChanged += new System.EventHandler(this.textBoxListViewTextAlternate_TextChanged);
this.textBoxListViewTextAlternate.Enter += new System.EventHandler(this.TextBoxListViewTextAlternateEnter);
this.textBoxListViewTextAlternate.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxListViewTextAlternateKeyDown);
this.textBoxListViewTextAlternate.KeyUp += new System.Windows.Forms.KeyEventHandler(this.TextBoxListViewTextAlternateKeyUp);
this.textBoxListViewTextAlternate.MouseMove += new System.Windows.Forms.MouseEventHandler(this.TextBoxListViewTextAlternateMouseMove);
//
// timeUpDownStartTime
//
this.timeUpDownStartTime.AutoSize = true;
this.timeUpDownStartTime.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.timeUpDownStartTime.Font = new System.Drawing.Font("Segoe UI", 9F);
this.timeUpDownStartTime.Location = new System.Drawing.Point(9, 26);
this.timeUpDownStartTime.Margin = new System.Windows.Forms.Padding(4);
this.timeUpDownStartTime.Name = "timeUpDownStartTime";
this.timeUpDownStartTime.Size = new System.Drawing.Size(96, 27);
this.timeUpDownStartTime.TabIndex = 0;
timeCode4.Hours = 0;
timeCode4.Milliseconds = 0;
timeCode4.Minutes = 0;
timeCode4.Seconds = 0;
timeCode4.TimeSpan = System.TimeSpan.Parse("00:00:00");
timeCode4.TotalMilliseconds = 0D;
timeCode4.TotalSeconds = 0D;
this.timeUpDownStartTime.TimeCode = timeCode4;
this.timeUpDownStartTime.UseVideoOffset = false;
//
// textBoxListViewText
//
this.textBoxListViewText.AllowDrop = true;
this.textBoxListViewText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxListViewText.ContextMenuStrip = this.contextMenuStripTextBoxListView;
this.textBoxListViewText.Enabled = false;
this.textBoxListViewText.HideSelection = false;
this.textBoxListViewText.Location = new System.Drawing.Point(236, 28);
this.textBoxListViewText.Multiline = true;
this.textBoxListViewText.Name = "textBoxListViewText";
this.textBoxListViewText.Size = new System.Drawing.Size(362, 63);
this.textBoxListViewText.TabIndex = 5;
this.textBoxListViewText.MouseClick += new System.Windows.Forms.MouseEventHandler(this.TextBoxListViewTextMouseClick);
this.textBoxListViewText.TextChanged += new System.EventHandler(this.TextBoxListViewTextTextChanged);
this.textBoxListViewText.Enter += new System.EventHandler(this.TextBoxListViewTextEnter);
this.textBoxListViewText.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxListViewTextKeyDown);
this.textBoxListViewText.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textBoxListViewText_KeyUp);
this.textBoxListViewText.Leave += new System.EventHandler(this.textBoxListViewText_Leave);
this.textBoxListViewText.MouseMove += new System.Windows.Forms.MouseEventHandler(this.textBoxListViewText_MouseMove);
//
// mediaPlayer
//
this.mediaPlayer.AllowDrop = true;
this.mediaPlayer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.mediaPlayer.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18)))));
this.mediaPlayer.CurrentPosition = 0D;
this.mediaPlayer.FontSizeFactor = 1F;
this.mediaPlayer.LastParagraph = null;
this.mediaPlayer.Location = new System.Drawing.Point(0, 0);
this.mediaPlayer.Margin = new System.Windows.Forms.Padding(0);
this.mediaPlayer.Name = "mediaPlayer";
this.mediaPlayer.ShowFullscreenButton = true;
this.mediaPlayer.ShowMuteButton = true;
this.mediaPlayer.ShowStopButton = true;
this.mediaPlayer.Size = new System.Drawing.Size(219, 246);
this.mediaPlayer.SmpteMode = false;
this.mediaPlayer.SubtitleText = "";
this.mediaPlayer.TabIndex = 5;
this.mediaPlayer.TextRightToLeft = System.Windows.Forms.RightToLeft.No;
this.mediaPlayer.VideoHeight = 0;
this.mediaPlayer.VideoPlayer = null;
this.mediaPlayer.VideoWidth = 0;
this.mediaPlayer.Volume = 0D;
this.mediaPlayer.DragDrop += new System.Windows.Forms.DragEventHandler(this.mediaPlayer_DragDrop);
this.mediaPlayer.DragEnter += new System.Windows.Forms.DragEventHandler(this.mediaPlayer_DragEnter);
//
// audioVisualizer
//
this.audioVisualizer.AllowDrop = true;
this.audioVisualizer.AllowNewSelection = true;
this.audioVisualizer.AllowOverlap = false;
this.audioVisualizer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.audioVisualizer.BackColor = System.Drawing.Color.Black;
this.audioVisualizer.BackgroundColor = System.Drawing.Color.Black;
this.audioVisualizer.Color = System.Drawing.Color.GreenYellow;
this.audioVisualizer.Font = new System.Drawing.Font("Segoe UI", 9F);
this.audioVisualizer.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(18)))));
this.audioVisualizer.Location = new System.Drawing.Point(472, 32);
this.audioVisualizer.Margin = new System.Windows.Forms.Padding(0);
this.audioVisualizer.Name = "audioVisualizer";
this.audioVisualizer.NewSelectionParagraph = null;
this.audioVisualizer.ParagraphColor = System.Drawing.Color.LimeGreen;
this.audioVisualizer.SceneChanges = ((System.Collections.Generic.List<double>)(resources.GetObject("audioVisualizer.SceneChanges")));
this.audioVisualizer.SelectedColor = System.Drawing.Color.Red;
this.audioVisualizer.ShowGridLines = true;
this.audioVisualizer.ShowSpectrogram = false;
this.audioVisualizer.ShowWaveform = true;
this.audioVisualizer.Size = new System.Drawing.Size(499, 229);
this.audioVisualizer.StartPositionSeconds = 0D;
this.audioVisualizer.TabIndex = 6;
this.audioVisualizer.TextBold = true;
this.audioVisualizer.TextColor = System.Drawing.Color.Gray;
this.audioVisualizer.TextSize = 9F;
this.audioVisualizer.VerticalZoomFactor = 1D;
this.audioVisualizer.WaveformNotLoadedText = "Click to add waveform";
this.audioVisualizer.WavePeaks = null;
this.audioVisualizer.ZoomFactor = 1D;
this.audioVisualizer.Click += new System.EventHandler(this.AudioWaveform_Click);
this.audioVisualizer.DragDrop += new System.Windows.Forms.DragEventHandler(this.AudioWaveformDragDrop);
this.audioVisualizer.DragEnter += new System.Windows.Forms.DragEventHandler(this.AudioWaveformDragEnter);
this.audioVisualizer.MouseEnter += new System.EventHandler(this.audioVisualizer_MouseEnter);
//
// timeUpDownVideoPosition
//
this.timeUpDownVideoPosition.AutoSize = true;
this.timeUpDownVideoPosition.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.timeUpDownVideoPosition.Font = new System.Drawing.Font("Segoe UI", 9F);
this.timeUpDownVideoPosition.Location = new System.Drawing.Point(96, 191);
this.timeUpDownVideoPosition.Margin = new System.Windows.Forms.Padding(4);
this.timeUpDownVideoPosition.Name = "timeUpDownVideoPosition";
this.timeUpDownVideoPosition.Size = new System.Drawing.Size(96, 27);
this.timeUpDownVideoPosition.TabIndex = 12;
timeCode5.Hours = 0;
timeCode5.Milliseconds = 0;
timeCode5.Minutes = 0;
timeCode5.Seconds = 0;
timeCode5.TimeSpan = System.TimeSpan.Parse("00:00:00");
timeCode5.TotalMilliseconds = 0D;
timeCode5.TotalSeconds = 0D;
this.timeUpDownVideoPosition.TimeCode = timeCode5;
this.timeUpDownVideoPosition.UseVideoOffset = false;
//
// timeUpDownVideoPositionAdjust
//
this.timeUpDownVideoPositionAdjust.AutoSize = true;
this.timeUpDownVideoPositionAdjust.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.timeUpDownVideoPositionAdjust.Font = new System.Drawing.Font("Segoe UI", 9F);
this.timeUpDownVideoPositionAdjust.Location = new System.Drawing.Point(96, 213);
this.timeUpDownVideoPositionAdjust.Margin = new System.Windows.Forms.Padding(4);
this.timeUpDownVideoPositionAdjust.Name = "timeUpDownVideoPositionAdjust";
this.timeUpDownVideoPositionAdjust.Size = new System.Drawing.Size(96, 27);
this.timeUpDownVideoPositionAdjust.TabIndex = 13;
timeCode6.Hours = 0;
timeCode6.Milliseconds = 0;
timeCode6.Minutes = 0;
timeCode6.Seconds = 0;
timeCode6.TimeSpan = System.TimeSpan.Parse("00:00:00");
timeCode6.TotalMilliseconds = 0D;
timeCode6.TotalSeconds = 0D;
this.timeUpDownVideoPositionAdjust.TimeCode = timeCode6;
this.timeUpDownVideoPositionAdjust.UseVideoOffset = false;
//
// Main
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -5181,5 +5190,6 @@
private System.Windows.Forms.ToolStripMenuItem generateTextFromCurrentVideoToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemSplitViaWaveform;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemEbuProperties;
private System.Windows.Forms.ToolStripMenuItem boxToolStripMenuItem;
}
}

View File

@ -1397,6 +1397,7 @@ namespace Nikse.SubtitleEdit.Forms
normalToolStripMenuItem1.Text = _language.Menu.ContextMenu.Normal;
boldToolStripMenuItem1.Text = _languageGeneral.Bold;
italicToolStripMenuItem1.Text = _languageGeneral.Italic;
boxToolStripMenuItem.Text = _language.Menu.ContextMenu.Box;
underlineToolStripMenuItem1.Text = _language.Menu.ContextMenu.Underline;
colorToolStripMenuItem1.Text = _language.Menu.ContextMenu.Color;
fontNameToolStripMenuItem.Text = _language.Menu.ContextMenu.FontName;
@ -7036,7 +7037,7 @@ namespace Nikse.SubtitleEdit.Forms
toolStripMenuItemAssStyles.Visible = false;
setStylesForSelectedLinesToolStripMenuItem.Text = _language.Menu.ContextMenu.SamiSetStyle;
}
else if ((formatType == typeof(WebVTT) && SubtitleListview1.SelectedItems.Count > 0))
else if (formatType == typeof(WebVTT) && SubtitleListview1.SelectedItems.Count > 0)
{
setStylesForSelectedLinesToolStripMenuItem.Visible = false;
toolStripMenuItemAssStyles.Visible = false;
@ -7080,6 +7081,25 @@ namespace Nikse.SubtitleEdit.Forms
setActorForSelectedLinesToolStripMenuItem.Visible = false;
}
if (formatType == typeof(Ebu))
{
Ebu.EbuGeneralSubtitleInformation header;
if (_subtitle != null && _subtitle.Header != null && (_subtitle.Header.Contains("STL2") || _subtitle.Header.Contains("STL3")))
{
header = Ebu.ReadHeader(Encoding.UTF8.GetBytes(_subtitle.Header));
}
else
{
header = new Ebu.EbuGeneralSubtitleInformation();
}
var open = header.DisplayStandardCode != "1" && header.DisplayStandardCode != "2";
boxToolStripMenuItem.Visible = open;
}
else
{
boxToolStripMenuItem.Visible = false;
}
toolStripMenuItemGoogleMicrosoftTranslateSelLine.Visible = false;
if (SubtitleListview1.SelectedItems.Count == 0)
{
@ -8007,6 +8027,12 @@ namespace Nikse.SubtitleEdit.Forms
}
}
}
else
{
if (!textBoxHasFocus)
lineTotal.Text = string.Format(_languageGeneral.TotalLengthX, s.Length);
}
UpdateListViewTextCharactersPerSeconds(charactersPerSecond, paragraph);
charactersPerSecond.Left = textBox.Left + (textBox.Width - labelCharactersPerSecond.Width);
lineTotal.Left = textBox.Left + (textBox.Width - lineTotal.Width);
@ -10954,6 +10980,15 @@ namespace Nikse.SubtitleEdit.Forms
mergedVobSubPacks[mergedVobSubPacks.Count - 2].EndTime = TimeSpan.FromMilliseconds(mergedVobSubPacks[mergedVobSubPacks.Count - 1].StartTime.TotalMilliseconds - 1);
}
// Remove bad packs
for (int i = mergedVobSubPacks.Count - 1; i >= 0; i--)
{
if (mergedVobSubPacks[i].SubPicture.SubPictureDateSize <= 2)
{
mergedVobSubPacks.RemoveAt(i);
}
}
using (var formSubOcr = new VobSubOcr())
{
formSubOcr.Initialize(mergedVobSubPacks, idx.Palette, Configuration.Settings.VobSubOcr, null); // TODO: language???
@ -13991,32 +14026,30 @@ namespace Nikse.SubtitleEdit.Forms
if (SubtitleListview1.SelectedItems.Count == 1 && tmp.Paragraphs.Count > 0)
{
MakeHistoryForUndo(_language.BeforeInsertLine);
_makeHistoryPaused = true;
Paragraph lastParagraph = null;
Paragraph lastTempParagraph = null;
var selectedIndices = new List<int>();
int firstIndex = FirstSelectedIndex;
foreach (var p in tmp.Paragraphs)
{
firstIndex++;
selectedIndices.Add(firstIndex);
InsertAfter();
textBoxListViewText.Text = p.Text;
if (lastParagraph != null)
{
double millisecondsBetween = p.StartTime.TotalMilliseconds - lastTempParagraph.EndTime.TotalMilliseconds;
timeUpDownStartTime.TimeCode = new TimeCode(lastParagraph.EndTime.TotalMilliseconds + millisecondsBetween);
}
SetDurationInSeconds(p.Duration.TotalSeconds);
lastParagraph = _subtitle.GetParagraphOrDefault(_subtitleListViewIndex);
lastTempParagraph = p;
var lastParagraph = _subtitle.Paragraphs[firstIndex];
double addMs = 0;
if (lastParagraph.EndTime.TotalMilliseconds > tmp.Paragraphs[0].StartTime.TotalMilliseconds)
{ // add time to pasted subtitles to prevent overlap, but only if necessary
addMs = lastParagraph.EndTime.TotalMilliseconds - tmp.Paragraphs[0].StartTime.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines;
}
SubtitleListview1.SelectIndexAndEnsureVisible(selectedIndices[0], true);
foreach (var idx in selectedIndices)
var selectIndices = new List<int>();
for (int i = 0; i < tmp.Paragraphs.Count; i++)
{
SubtitleListview1.Items[idx].Selected = true;
var p = tmp.Paragraphs[i];
p.StartTime.TotalMilliseconds += addMs;
p.EndTime.TotalMilliseconds += addMs;
_subtitle.Paragraphs.Insert(firstIndex + i + 1, p);
selectIndices.Insert(0, firstIndex + i + 1);
}
RestartHistory();
SubtitleListview1.Fill(_subtitle, _subtitleAlternate);
SubtitleListview1.BeginUpdate();
SubtitleListview1.SelectIndexAndEnsureVisible(firstIndex + 1, true);
foreach (var selectIndex in selectIndices)
{
SubtitleListview1.Items[selectIndex].Selected = true;
}
SubtitleListview1.EndUpdate();
}
else if (SubtitleListview1.Items.Count == 0 && tmp.Paragraphs.Count > 0)
{ // insert into empty subtitle
@ -19817,6 +19850,8 @@ namespace Nikse.SubtitleEdit.Forms
return;
}
var oldParagraph = new Paragraph(p, false);
//if (autoDuration)
//{
// // TODO: auto duration
@ -19847,6 +19882,8 @@ namespace Nikse.SubtitleEdit.Forms
if (durationInSeconds >= numericUpDownDuration.Minimum && durationInSeconds <= numericUpDownDuration.Maximum)
SetDurationInSeconds((double)durationInSeconds);
UpdateOriginalTimeCodes(oldParagraph);
if (goToNext)
SubtitleListview1.SelectIndexAndEnsureVisible(index + 1, true);
@ -20027,7 +20064,7 @@ namespace Nikse.SubtitleEdit.Forms
}
var formatType = GetCurrentSubtitleFormat().GetType();
if ((formatType == typeof(WebVTT) && tb.SelectionLength > 0))
if (formatType == typeof(WebVTT) && tb.SelectionLength > 0)
{
toolStripSeparatorWebVTT.Visible = true;
toolStripMenuItemWebVttVoice.Visible = true;
@ -20817,37 +20854,54 @@ namespace Nikse.SubtitleEdit.Forms
SubtitleListview1.BeginUpdate();
foreach (int i in indices)
{
var pre = string.Empty;
int indexOfEndBracket = -1;
if (_subtitleAlternate != null && Configuration.Settings.General.AllowEditOfOriginalSubtitle)
{
var original = Utilities.GetOriginalParagraph(i, _subtitle.Paragraphs[i], _subtitleAlternate.Paragraphs);
if (original != null)
{
pre = string.Empty;
indexOfEndBracket = original.Text.IndexOf('}');
if (original.Text.StartsWith("{\\", StringComparison.Ordinal) && indexOfEndBracket > 1)
{
pre = original.Text.Substring(0, indexOfEndBracket + 1);
original.Text = original.Text.Remove(0, indexOfEndBracket + 1);
}
if (original.Text.Contains(tag))
{
original.Text = original.Text.Replace(tag, string.Empty);
original.Text = original.Text.Replace(Environment.NewLine + " ", Environment.NewLine).Replace(" " + Environment.NewLine, Environment.NewLine).Trim();
original.Text = original.Text.Replace(tag, string.Empty).Trim();
original.Text = pre + original.Text.Replace(Environment.NewLine + " ", Environment.NewLine).Replace(" " + Environment.NewLine, Environment.NewLine).Trim();
}
else
{
if (Configuration.Settings.Tools.MusicSymbolStyle.Equals("single", StringComparison.OrdinalIgnoreCase))
original.Text = string.Format("{0} {1}", tag, original.Text.Replace(Environment.NewLine, Environment.NewLine + tag + " "));
original.Text = string.Format("{0}{1} {2}", pre, tag, original.Text.Replace(Environment.NewLine, Environment.NewLine + tag + " "));
else
original.Text = string.Format("{0} {1} {0}", tag, original.Text.Replace(Environment.NewLine, " " + tag + Environment.NewLine + tag + " "));
original.Text = string.Format("{0}{1} {2} {1}", pre, tag, original.Text.Replace(Environment.NewLine, " " + tag + Environment.NewLine + tag + " "));
}
SubtitleListview1.SetAlternateText(i, original.Text);
}
}
pre = string.Empty;
var p = _subtitle.Paragraphs[i];
indexOfEndBracket = p.Text.IndexOf('}');
if (p.Text.StartsWith("{\\", StringComparison.Ordinal) && indexOfEndBracket > 1)
{
pre = p.Text.Substring(0, indexOfEndBracket + 1);
p.Text = p.Text.Remove(0, indexOfEndBracket + 1);
}
if (_subtitle.Paragraphs[i].Text.Contains(tag))
{
_subtitle.Paragraphs[i].Text = _subtitle.Paragraphs[i].Text.Replace("♪", string.Empty).Replace(Environment.NewLine + " ", Environment.NewLine).Replace(" " + Environment.NewLine, Environment.NewLine).Trim();
_subtitle.Paragraphs[i].Text = pre + _subtitle.Paragraphs[i].Text.Replace("♪", string.Empty).Replace(Environment.NewLine + " ", Environment.NewLine).Replace(" " + Environment.NewLine, Environment.NewLine).Trim();
}
else
{
if (Configuration.Settings.Tools.MusicSymbolStyle.Equals("single", StringComparison.OrdinalIgnoreCase))
_subtitle.Paragraphs[i].Text = string.Format("{0} {1}", tag, _subtitle.Paragraphs[i].Text.Replace(Environment.NewLine, Environment.NewLine + tag + " "));
p.Text = string.Format("{0}{1} {2}", pre, tag, p.Text.Replace(Environment.NewLine, Environment.NewLine + tag + " "));
else
_subtitle.Paragraphs[i].Text = string.Format("{0} {1} {0}", tag, _subtitle.Paragraphs[i].Text.Replace(Environment.NewLine, " " + tag + Environment.NewLine + tag + " "));
p.Text = string.Format("{0}{1} {2} {1}", pre, tag, p.Text.Replace(Environment.NewLine, " " + tag + Environment.NewLine + tag + " "));
}
SubtitleListview1.SetText(i, _subtitle.Paragraphs[i].Text);
}
@ -21668,7 +21722,7 @@ namespace Nikse.SubtitleEdit.Forms
{
if (form.PasteAll)
{
for (int k = _subtitle.Paragraphs.Count - 2; k > index; k--)
for (int k = _subtitle.Paragraphs.Count - 2; k >= index; k--)
{
_subtitle.Paragraphs[k + 1] = new Paragraph(_subtitle.Paragraphs[k]);
}
@ -21677,7 +21731,7 @@ namespace Nikse.SubtitleEdit.Forms
}
else if (form.PasteTimeCodesOnly)
{
for (int k = _subtitle.Paragraphs.Count - 2; k > index; k--)
for (int k = _subtitle.Paragraphs.Count - 2; k >= index; k--)
{
_subtitle.Paragraphs[k + 1].StartTime.TotalMilliseconds = _subtitle.Paragraphs[k].StartTime.TotalMilliseconds;
_subtitle.Paragraphs[k + 1].EndTime.TotalMilliseconds = _subtitle.Paragraphs[k].EndTime.TotalMilliseconds;
@ -21687,17 +21741,17 @@ namespace Nikse.SubtitleEdit.Forms
}
else if (form.PasteTextOnly)
{
for (int k = _subtitle.Paragraphs.Count - 2; k > index; k--)
for (int k = _subtitle.Paragraphs.Count - 2; k >= index; k--)
{
_subtitle.Paragraphs[k + 1].Text = _subtitle.Paragraphs[k].Text;
}
}
else if (form.PasteOriginalTextOnly)
{
for (int k = _subtitle.Paragraphs.Count - 2; k > index; k--)
for (int k = _subtitle.Paragraphs.Count - 2; k >= index; k--)
{
var original = Utilities.GetOriginalParagraph(index, _subtitle.Paragraphs[k], _subtitleAlternate.Paragraphs);
var originalNext = Utilities.GetOriginalParagraph(index, _subtitle.Paragraphs[k + 1], _subtitleAlternate.Paragraphs);
var original = Utilities.GetOriginalParagraph(k, _subtitle.Paragraphs[k], _subtitleAlternate.Paragraphs);
var originalNext = Utilities.GetOriginalParagraph(k + 1, _subtitle.Paragraphs[k + 1], _subtitleAlternate.Paragraphs);
if (original != null)
{
originalNext.Text = original.Text;
@ -21714,15 +21768,75 @@ namespace Nikse.SubtitleEdit.Forms
}
if (form.PasteOverwrite)
{
for (int i = 0; i + index < _subtitle.Paragraphs.Count && i < tmp.Paragraphs.Count; i++)
_subtitle.Paragraphs[index + i].Text = tmp.Paragraphs[i].Text;
for (int i = 0; i < tmp.Paragraphs.Count; i++)
{
if (form.PasteAll)
{
if (index + i < _subtitle.Paragraphs.Count)
{
_subtitle.Paragraphs[index + i].Text = tmp.Paragraphs[i].Text;
_subtitle.Paragraphs[index + i].StartTime.TotalMilliseconds = tmp.Paragraphs[i].StartTime.TotalMilliseconds;
_subtitle.Paragraphs[index + i].EndTime.TotalMilliseconds = tmp.Paragraphs[i].EndTime.TotalMilliseconds;
}
}
else if (form.PasteTimeCodesOnly)
{
if (index + i < _subtitle.Paragraphs.Count)
{
_subtitle.Paragraphs[index + i].StartTime.TotalMilliseconds = tmp.Paragraphs[i].StartTime.TotalMilliseconds;
_subtitle.Paragraphs[index + i].EndTime.TotalMilliseconds = tmp.Paragraphs[i].EndTime.TotalMilliseconds;
}
}
else if (form.PasteTextOnly)
{
if (index + i < _subtitle.Paragraphs.Count)
{
_subtitle.Paragraphs[index + i].Text = tmp.Paragraphs[i].Text;
}
}
else if (form.PasteOriginalTextOnly)
{
if (index + i < _subtitle.Paragraphs.Count)
{
var original = Utilities.GetOriginalParagraph(index + i, _subtitle.Paragraphs[index + i], _subtitleAlternate.Paragraphs);
if (original != null)
{
original.Text = tmp.Paragraphs[i].Text;
}
}
}
}
}
else
{
for (int i = 0; i + index < _subtitle.Paragraphs.Count && i < tmp.Paragraphs.Count; i++)
{
if (index + i + 1 < _subtitle.Paragraphs.Count)
_subtitle.Paragraphs[index + i + 1].Text = tmp.Paragraphs[i].Text;
if (index + i < _subtitle.Paragraphs.Count)
{
if (form.PasteAll)
{
_subtitle.Paragraphs[index + i].Text = tmp.Paragraphs[i].Text;
_subtitle.Paragraphs[index + i].StartTime.TotalMilliseconds = tmp.Paragraphs[i].StartTime.TotalMilliseconds;
_subtitle.Paragraphs[index + i].EndTime.TotalMilliseconds = tmp.Paragraphs[i].EndTime.TotalMilliseconds;
}
else if (form.PasteTimeCodesOnly)
{
_subtitle.Paragraphs[index + i].StartTime.TotalMilliseconds = tmp.Paragraphs[i].StartTime.TotalMilliseconds;
_subtitle.Paragraphs[index + i].EndTime.TotalMilliseconds = tmp.Paragraphs[i].EndTime.TotalMilliseconds;
}
else if (form.PasteTextOnly)
{
_subtitle.Paragraphs[index + i].Text = tmp.Paragraphs[i].Text;
}
else if (form.PasteOriginalTextOnly)
{
var original = Utilities.GetOriginalParagraph(index + i, _subtitle.Paragraphs[index + i], _subtitleAlternate.Paragraphs);
if (original != null)
{
original.Text = tmp.Paragraphs[i].Text;
}
}
}
}
}
@ -22946,6 +23060,11 @@ namespace Nikse.SubtitleEdit.Forms
form.ShowDialog(this);
}
}
private void boxToolStripMenuItem_Click(object sender, EventArgs e)
{
ListViewToggleTag("box");
}
}
}

View File

@ -462,19 +462,19 @@
<data name="toolStripButtonNetflixQualityCheck.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALoSURBVFhHtZfPaxNBFMdHs7/GpNns7vQoeNWDZw969+Ld
g3+AF+8eBE9iFSuCQgO2oKXY+qNNQhEsFoOnUqqg0JbSimn2h+BBvFQEf3R9L0zCdvYVzCb7he9p3tv3
yZt9sxN2mDYsN464SLmtVc7JEFINw44pX2dMkyH/pzdmhQQITW9ehpCiiqP7BlgEgB3LSwGsc/GnZdon
ZFhKVHF03wA3DHt/2aC7EHBvXIalRBVHZwKY1cpxm+hCZIrv64yVZOgBUcXRmQBqejluGk4aAOybo1dk
6AFRxdGZADBxqlAmASLL2YaHHpXhPamFu84MMAnbsGbSIxkalQsyvCe1cNeZAZ7CNkxrNgngW2JZhvek
Fu46MwD6dmEk3iQOpiUu9gO9clqmdJQsmvRAABPaSLyg010ILG9SpnSULJr0QADT8B7cgS58pkaS2z+3
WWlUpuUDgOM4BgBLhxxMoSWuyTT2HGKThbseCAB9DwDug6HgLxUg0u0vcDAZmPcIupXM63pgABxH7ELA
3dkUADiwKpcw7wHEJPO6HhgAx7EDoLlnSABTvMO8WxCzQGzDwABoHEdciwxvhYJoa85ZhMSXVs0dCgCO
I675urhIAcBd4QUCYJyaOxQA/GW41oSHRdzzVQC8K+A7gJ3CyUnmDgUAHyqXWWA5V1UA9GsYVezCTB4A
aLnMfFZ2t3jphwqwC4cVHlpVZRuGDoCKLFFVAdB1vRKPA0QyLxeAluGexA+SCrAFXcBxfJLYhlwAUKHl
vVIB0DPwCX+Y2IbcAPxjznkK4D1cYu4mtiE3ANCRgItNCqIKYzsntyFPABZy7zIF8BYutPgNwbxcAT4w
VoSr+jcVwIeXcUJuQ64AqJCLMRUA/RJG8hlsQ/4AzDne4uK3CvAJuvAYtiF3ABT8ZZtTAdB1uE/2DTBv
FPcahWKrodurdb28WDPKUzXdvimXSe0a7qlVw15Zgz8tH3Xn6wYv7u1AV5pc/KUBGPsH8xCt33v4vv0A
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALoSURBVFhHtZfPaxNBFMdHs7/GpLvZ7PQoeNWDZw969+Ld
g3+AF+8eBPFkFSuCQgO2oKXY+qNNQikoFoOnUqqg0JbSiml2s4IH8VIR/NH1vTAbtrOvYDbZL3xP896+
T97sm52ww7RhVaKQi5TbWvmcDCHVMJyI8nXGNBnyf3pjlkmAjunNyxBSVHF03wCLALBjeSmAdS7+tEzn
hAxLiSqO7hvghuHsLxt0FwLujcuwlKji6EwAs5odtYkuhKb4vs5YSYYeEFUcnQmgpttR03DTAGDfHL0i
Qw+IKo7OBICJUwWbBAgtdxseelSG96QWjp0ZYBK2Yc2kR7JjlC/I8J7UwrEzAzyFbZjWHBLAt8SyDO9J
LRw7MwD6dmEk2iQOpiUu9gO9fFqmdJUsmvRAABPaSLSg010ILG9SpnSVLJr0QADT8B7cgS58pkaSOz+3
WWlUpuUDgOM4BgCvDjmYOpa4JtPYc4hNFo49EAD6HgDcB0PBXypAqDtf4GAyMO8RdCuZF3tgABxH7ELA
K7MpAHBglS9h3gOISebFHhgAx7ELoFXOkACmeId5tyBmgdiGgQHQOI64FhreCgXR1tyzCIkvrZo7FAAc
R1zzdXGRAoC7wgsEwDg1dygA+MtwrQkPC7nnqwB4V8B3ADuFk5PMHQoAPlQus8Byr6oA6NcwqtiFmTwA
0HKZ+cyubPHSDxVgFw4rPLSqyjYMHQAVWqKqAqDrejkaB4hkXi4ALaNyEj9IKsAWdAHH8UliG3IBQHUs
76UKgJ6BT/jDxDbkBuAfc89TAO/hEnM3sQ25AYCOBFxsUhBVGNs5uQ15ArAO9y5TAG/hQovfEMzLFeAD
Y0W4qn9TAXx4GSfkNuQKgOpwMaYCoJdgJJ/BNuQPwNzjLS5+qwCfoAuPYRtyB0DBX7Y5FQBdh/tk3wDz
RnGvUSi2GrqzWtftxZphT9V056ZcJrVrVE6tGs7KGvxp+ai7Xzd4cW8HutLk4i8NwNg/Un+tZ4UM7sQA
AAAASUVORK5CYII=
</value>
</data>
@ -650,9 +650,15 @@
<metadata name="colorDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>813, 17</value>
</metadata>
<metadata name="toolStripWaveControls.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>650, 56</value>
</metadata>
<data name="audioVisualizer.SceneChanges" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAJoBbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1u
ZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0sIG1zY29ybGliLCBWZXJzaW9u
PTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OQUB
AAAAMFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkRvdWJsZQMAAAAGX2l0
ZW1zBV9zaXplCF92ZXJzaW9uBwAABggIAgAAAAkDAAAAAAAAAAAAAAAPAwAAAAAAAAAGCw==
</value>
</data>
<metadata name="toolStripWaveControls.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>650, 56</value>
</metadata>
@ -762,7 +768,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAD2
CAAAAk1TRnQBSQFMAgEBAgEAAQgBJQEIASUBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
CAAAAk1TRnQBSQFMAgEBAgEAASgBJQEoASUBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@ -809,15 +815,6 @@
<metadata name="timerAlternateTextUndo.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>916, 95</value>
</metadata>
<data name="audioVisualizer.SceneChanges" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAJoBbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1u
ZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0sIG1zY29ybGliLCBWZXJzaW9u
PTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OQUB
AAAAMFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkRvdWJsZQMAAAAGX2l0
ZW1zBV9zaXplCF92ZXJzaW9uBwAABggIAgAAAAkDAAAAAAAAAAAAAAAPAwAAAAAAAAAGCw==
</value>
</data>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>145</value>
</metadata>

View File

@ -59,7 +59,7 @@
this.groupBoxInspectItems.Controls.Add(this.listBoxInspectItems);
this.groupBoxInspectItems.Location = new System.Drawing.Point(12, 12);
this.groupBoxInspectItems.Name = "groupBoxInspectItems";
this.groupBoxInspectItems.Size = new System.Drawing.Size(455, 287);
this.groupBoxInspectItems.Size = new System.Drawing.Size(521, 284);
this.groupBoxInspectItems.TabIndex = 1;
this.groupBoxInspectItems.TabStop = false;
//
@ -156,7 +156,7 @@
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonCancel.Location = new System.Drawing.Point(392, 305);
this.buttonCancel.Location = new System.Drawing.Point(458, 302);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 21);
this.buttonCancel.TabIndex = 0;
@ -169,7 +169,7 @@
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.buttonOK.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonOK.Location = new System.Drawing.Point(311, 305);
this.buttonOK.Location = new System.Drawing.Point(377, 302);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(75, 21);
this.buttonOK.TabIndex = 2;
@ -181,7 +181,7 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(479, 338);
this.ClientSize = new System.Drawing.Size(545, 335);
this.Controls.Add(this.groupBoxInspectItems);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonOK);

View File

@ -20,16 +20,27 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private List<VobSubOcr.CompareMatch> _matches;
private List<ImageSplitterItem> _splitterItems;
private int _startIndex;
int _extraCount = 0;
internal void Initialize(int selectedIndex, List<VobSubOcr.CompareMatch> matches, List<ImageSplitterItem> splitterItems)
{
_startIndex = selectedIndex;
for (int i = 0; i < selectedIndex; i++)
{
if (matches[i].Extra != null && matches[i].Extra.Count > 0)
_extraCount += matches[i].Extra.Count -1;
}
_matches = matches;
_splitterItems = splitterItems;
int count = 0;
for (int i = selectedIndex; i < _splitterItems.Count; i++)
for (int i = _startIndex; i < _splitterItems.Count - _extraCount; i++)
{
if (i >= _matches.Count)
break;
var m = _matches[i];
if (m.Extra?.Count > 0)
break;
if (m.Text != Configuration.Settings.Language.VobSubOcr.NoMatch && (m.ImageSplitterItem?.NikseBitmap == null || !string.IsNullOrWhiteSpace(m.ImageSplitterItem.SpecialCharacter)))
break;
count++;
@ -45,14 +56,14 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
{
for (int i = 0; i < listBoxInspectItems.Items.Count; i++)
{
listBoxInspectItems.SetSelected(listBoxInspectItems.Items.Count - 1, i < numericUpDownExpandCount.Value);
listBoxInspectItems.SetSelected(i, i < numericUpDownExpandCount.Value);
}
MakeExpandImage();
}
private void MakeExpandImage()
{
var splitterItem = _splitterItems[_startIndex];
var splitterItem = _splitterItems[_startIndex + _extraCount];
if (splitterItem.NikseBitmap == null)
return;
ExpandedMatch = new BinaryOcrBitmap(new NikseBitmap(splitterItem.NikseBitmap), false, (int)numericUpDownExpandCount.Value, string.Empty, splitterItem.X, splitterItem.Y) { ExpandedList = new List<BinaryOcrBitmap>() };
@ -60,13 +71,17 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
{
if (i < numericUpDownExpandCount.Value)
{
splitterItem = _splitterItems[_startIndex + i];
splitterItem = _splitterItems[_startIndex + i + _extraCount];
if (splitterItem.NikseBitmap == null)
break;
ExpandedMatch.ExpandedList.Add(new BinaryOcrBitmap(splitterItem.NikseBitmap, false, 0, null, splitterItem.X, splitterItem.Y));
}
}
pictureBoxInspectItem.Image = ExpandedMatch.ToOldBitmap();
var newBmp = ExpandedMatch.ToOldBitmap();
pictureBoxInspectItem.Image = newBmp;
pictureBoxInspectItem.Width = newBmp.Width;
pictureBoxInspectItem.Height = newBmp.Height;
}
private void buttonOK_Click(object sender, System.EventArgs e)

View File

@ -13,7 +13,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
{
InitializeComponent();
var wc = new WebClient { Proxy = Utilities.GetProxy() };
wc.DownloadDataAsync(new Uri("https://github.com/SubtitleEdit/support-files/raw/master/Tesseract4.tar.gz"));
wc.DownloadDataAsync(new Uri("https://github.com/SubtitleEdit/support-files/raw/master/Tesseract400.tar.gz"));
wc.DownloadDataCompleted += wc_DownloadDataCompleted;
wc.DownloadProgressChanged += (o, args) =>
{
@ -25,7 +25,9 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
{
if (e.Error != null)
{
MessageBox.Show(Configuration.Settings.Language.GetTesseractDictionaries.DownloadFailed);
MessageBox.Show(Configuration.Settings.Language.GetTesseractDictionaries.DownloadFailed + Environment.NewLine +
Environment.NewLine +
e.Error.Message + ": " + e.Error.StackTrace);
DialogResult = DialogResult.Cancel;
return;
}

View File

@ -45,8 +45,8 @@
this.groupBoxCropping = new System.Windows.Forms.GroupBox();
this.checkBoxCropTransparent = new System.Windows.Forms.CheckBox();
this.groupBoxColors = new System.Windows.Forms.GroupBox();
this.checkBoxInvertColors = new System.Windows.Forms.CheckBox();
this.checkBoxYellowToWhite = new System.Windows.Forms.CheckBox();
this.checkBoxInvertColors = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownThreshold)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxSubtitleImage)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
@ -73,7 +73,7 @@
0,
0});
this.numericUpDownThreshold.Minimum = new decimal(new int[] {
50,
1,
0,
0,
0});
@ -240,6 +240,16 @@
this.groupBoxColors.TabStop = false;
this.groupBoxColors.Text = "Colors";
//
// checkBoxYellowToWhite
//
this.checkBoxYellowToWhite.AutoSize = true;
this.checkBoxYellowToWhite.Location = new System.Drawing.Point(9, 42);
this.checkBoxYellowToWhite.Name = "checkBoxYellowToWhite";
this.checkBoxYellowToWhite.Size = new System.Drawing.Size(97, 17);
this.checkBoxYellowToWhite.TabIndex = 28;
this.checkBoxYellowToWhite.Text = "Yellow to white";
this.checkBoxYellowToWhite.UseVisualStyleBackColor = true;
//
// checkBoxInvertColors
//
this.checkBoxInvertColors.AutoSize = true;
@ -251,17 +261,7 @@
this.checkBoxInvertColors.UseVisualStyleBackColor = true;
this.checkBoxInvertColors.CheckedChanged += new System.EventHandler(this.checkBoxInvertColors_CheckedChanged);
//
// checkBoxYellowToWhite
//
this.checkBoxYellowToWhite.AutoSize = true;
this.checkBoxYellowToWhite.Location = new System.Drawing.Point(9, 42);
this.checkBoxYellowToWhite.Name = "checkBoxYellowToWhite";
this.checkBoxYellowToWhite.Size = new System.Drawing.Size(97, 17);
this.checkBoxYellowToWhite.TabIndex = 28;
this.checkBoxYellowToWhite.Text = "Yellow to white";
this.checkBoxYellowToWhite.UseVisualStyleBackColor = true;
//
// SetForeColorThreshold
// OcrPreprocessingSettings
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
@ -279,7 +279,7 @@
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(790, 481);
this.Name = "SetForeColorThreshold";
this.Name = "OcrPreprocessingSettings";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "OCR image preprocessing";

View File

@ -0,0 +1,201 @@
namespace Nikse.SubtitleEdit.Forms.Ocr
{
partial class OcrPreprocessingT4
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.labelDescription = new System.Windows.Forms.Label();
this.numericUpDownThreshold = new System.Windows.Forms.NumericUpDown();
this.pictureBoxSubtitleImage = new System.Windows.Forms.PictureBox();
this.buttonCancel = new System.Windows.Forms.Button();
this.buttonOK = new System.Windows.Forms.Button();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.colorDialog1 = new System.Windows.Forms.ColorDialog();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.groupBoxBinaryImageCompareThresshold = new System.Windows.Forms.GroupBox();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownThreshold)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxSubtitleImage)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.groupBoxBinaryImageCompareThresshold.SuspendLayout();
this.SuspendLayout();
//
// labelDescription
//
this.labelDescription.AutoSize = true;
this.labelDescription.Location = new System.Drawing.Point(17, 58);
this.labelDescription.Name = "labelDescription";
this.labelDescription.Size = new System.Drawing.Size(372, 13);
this.labelDescription.TabIndex = 16;
this.labelDescription.Text = "Adjust value until text is shown clearly (normally values between 200 and 300)";
//
// numericUpDownThreshold
//
this.numericUpDownThreshold.Location = new System.Drawing.Point(20, 32);
this.numericUpDownThreshold.Maximum = new decimal(new int[] {
765,
0,
0,
0});
this.numericUpDownThreshold.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.numericUpDownThreshold.Name = "numericUpDownThreshold";
this.numericUpDownThreshold.Size = new System.Drawing.Size(57, 20);
this.numericUpDownThreshold.TabIndex = 15;
this.numericUpDownThreshold.Value = new decimal(new int[] {
200,
0,
0,
0});
this.numericUpDownThreshold.ValueChanged += new System.EventHandler(this.numericUpDownThreshold_ValueChanged);
//
// pictureBoxSubtitleImage
//
this.pictureBoxSubtitleImage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pictureBoxSubtitleImage.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pictureBoxSubtitleImage.Location = new System.Drawing.Point(12, 247);
this.pictureBoxSubtitleImage.Name = "pictureBoxSubtitleImage";
this.pictureBoxSubtitleImage.Size = new System.Drawing.Size(804, 135);
this.pictureBoxSubtitleImage.TabIndex = 14;
this.pictureBoxSubtitleImage.TabStop = false;
this.pictureBoxSubtitleImage.Click += new System.EventHandler(this.pictureBoxSubtitleImage_Click);
//
// buttonCancel
//
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonCancel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonCancel.Location = new System.Drawing.Point(741, 558);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 21);
this.buttonCancel.TabIndex = 13;
this.buttonCancel.Text = "C&ancel";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
//
// buttonOK
//
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonOK.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonOK.Location = new System.Drawing.Point(660, 558);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(75, 21);
this.buttonOK.TabIndex = 12;
this.buttonOK.Text = "&OK";
this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
//
// pictureBox1
//
this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pictureBox1.Location = new System.Drawing.Point(12, 412);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(804, 140);
this.pictureBox1.TabIndex = 17;
this.pictureBox1.TabStop = false;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(12, 231);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(73, 13);
this.label2.TabIndex = 21;
this.label2.Text = "Original image";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(12, 396);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(132, 13);
this.label3.TabIndex = 22;
this.label3.Text = "Image after pre-processing";
//
// groupBoxBinaryImageCompareThresshold
//
this.groupBoxBinaryImageCompareThresshold.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBoxBinaryImageCompareThresshold.Controls.Add(this.numericUpDownThreshold);
this.groupBoxBinaryImageCompareThresshold.Controls.Add(this.labelDescription);
this.groupBoxBinaryImageCompareThresshold.Location = new System.Drawing.Point(15, 12);
this.groupBoxBinaryImageCompareThresshold.Name = "groupBoxBinaryImageCompareThresshold";
this.groupBoxBinaryImageCompareThresshold.Size = new System.Drawing.Size(801, 216);
this.groupBoxBinaryImageCompareThresshold.TabIndex = 29;
this.groupBoxBinaryImageCompareThresshold.TabStop = false;
//
// OcrPreprocessingT4
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(828, 591);
this.Controls.Add(this.groupBoxBinaryImageCompareThresshold);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.pictureBoxSubtitleImage);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonOK);
this.KeyPreview = true;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(790, 481);
this.Name = "OcrPreprocessingT4";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "OCR image preprocessing";
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.SetForeColorThreshold_KeyDown);
((System.ComponentModel.ISupportInitialize)(this.numericUpDownThreshold)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxSubtitleImage)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.groupBoxBinaryImageCompareThresshold.ResumeLayout(false);
this.groupBoxBinaryImageCompareThresshold.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label labelDescription;
private System.Windows.Forms.NumericUpDown numericUpDownThreshold;
private System.Windows.Forms.PictureBox pictureBoxSubtitleImage;
private System.Windows.Forms.Button buttonCancel;
private System.Windows.Forms.Button buttonOK;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.ColorDialog colorDialog1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.GroupBox groupBoxBinaryImageCompareThresshold;
}
}

View File

@ -0,0 +1,84 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using Nikse.SubtitleEdit.Core;
using Nikse.SubtitleEdit.Logic.Ocr;
using Bitmap = System.Drawing.Bitmap;
namespace Nikse.SubtitleEdit.Forms.Ocr
{
public partial class OcrPreprocessingT4 : Form
{
private readonly bool _isBinaryImageCompare;
private readonly NikseBitmap _source;
public PreprocessingSettings PreprocessingSettings { get; }
public OcrPreprocessingT4(Bitmap bitmap, bool isBinaryImageCompare, PreprocessingSettings preprocessingSettings)
{
_isBinaryImageCompare = isBinaryImageCompare;
InitializeComponent();
_source = new NikseBitmap(bitmap);
pictureBoxSubtitleImage.Image = bitmap;
if (preprocessingSettings != null)
{
PreprocessingSettings = preprocessingSettings;
}
else
{
PreprocessingSettings = new PreprocessingSettings
{
BinaryImageCompareThresshold = Configuration.Settings.Tools.OcrBinaryImageCompareRgbThreshold
};
}
numericUpDownThreshold.Value = PreprocessingSettings.BinaryImageCompareThresshold;
RefreshImage();
}
private void numericUpDownThreshold_ValueChanged(object sender, EventArgs e)
{
RefreshImage();
}
private void RefreshImage()
{
PreprocessingSettings.BinaryImageCompareThresshold = (int)numericUpDownThreshold.Value;
pictureBox1.Image?.Dispose();
var n = new NikseBitmap(_source);
n.MakeTwoColor((int)numericUpDownThreshold.Value, Color.White, Color.Black);
pictureBox1.Image = n.GetBitmap();
}
private void buttonOK_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
}
private void pictureBoxSubtitleImage_Click(object sender, EventArgs e)
{
var bmp = pictureBoxSubtitleImage.Image as Bitmap;
if (bmp == null)
return;
}
private void SetForeColorThreshold_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
DialogResult = DialogResult.Cancel;
}
}
private void checkBoxCropTransparent_CheckedChanged(object sender, EventArgs e)
{
RefreshImage();
}
}
}

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="colorDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -304,7 +304,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private readonly DateTime _windowStartTime = DateTime.Now;
private int _linesOcred;
private bool _okClicked;
private Dictionary<string, int> _unknownWordsDictionary = new Dictionary<string, int>();
private readonly Dictionary<string, int> _unknownWordsDictionary;
// optimization vars
private int _numericUpDownPixelsIsSpace = 6;
@ -312,7 +312,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private int _ocrMethodIndex;
private bool _autoBreakLines;
private readonly int _ocrMethodTesseract;
private readonly int _ocrMethodTesseract4;
private readonly int _ocrMethodModi;
private readonly int _ocrMethodBinaryImageCompare;
private readonly int _ocrMethodNocr;
@ -335,6 +335,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
UiUtil.FixFonts(this);
SetDoubleBuffered(subtitleListView1);
_unknownWordsDictionary = new Dictionary<string, int>();
var language = Configuration.Settings.Language.VobSubOcr;
Text = language.Title;
groupBoxOcrMethod.Text = language.OcrMethod;
@ -417,7 +418,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
comboBoxOcrMethod.Items.Clear();
comboBoxOcrMethod.Items.Add("Binary image compare");
comboBoxOcrMethod.Items.Add("Tesseract 3.02");
comboBoxOcrMethod.Items.Add("Tesseract 4 Beta");
comboBoxOcrMethod.Items.Add("Tesseract 4.00");
if (_modiEnabled)
comboBoxOcrMethod.Items.Add(language.OcrViaModi);
if (Configuration.Settings.General.ShowBetaStuff)
@ -427,7 +428,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
}
_ocrMethodBinaryImageCompare = comboBoxOcrMethod.Items.IndexOf("Binary image compare");
_ocrMethodTesseract302 = comboBoxOcrMethod.Items.IndexOf("Tesseract 3.02");
_ocrMethodTesseract = comboBoxOcrMethod.Items.IndexOf("Tesseract 4 Beta");
_ocrMethodTesseract4 = comboBoxOcrMethod.Items.IndexOf("Tesseract 4.00");
_ocrMethodModi = comboBoxOcrMethod.Items.IndexOf(language.OcrViaModi);
_ocrMethodNocr = comboBoxOcrMethod.Items.IndexOf(language.OcrViaNOCR);
@ -463,6 +464,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
checkBoxRightToLeft.Checked = Configuration.Settings.VobSubOcr.RightToLeft;
toolStripMenuItemSetUnItalicFactor.Text = language.SetUnitalicFactor;
deleteToolStripMenuItem.Text = Configuration.Settings.Language.Main.Menu.ContextMenu.Delete;
setForecolorThresholdToolStripMenuItem.Text = language.ImagePreProcessing;
toolStripMenuItemExport.Text = Configuration.Settings.Language.Main.Menu.File.Export;
vobSubToolStripMenuItem.Text = Configuration.Settings.Language.Main.Menu.File.ExportVobSub;
@ -541,7 +543,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
checkBoxPromptForUnknownWords.Checked = false;
int max = GetSubtitleCount();
if (_ocrMethodIndex == _ocrMethodTesseract && _tesseractAsyncStrings == null)
if (_ocrMethodIndex == _ocrMethodTesseract4 && _tesseractAsyncStrings == null)
{
_tesseractAsyncStrings = new string[max];
_tesseractAsyncIndex = (int)numericUpDownStartNumber.Value + 5;
@ -734,7 +736,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
checkBoxPromptForUnknownWords.Checked = false;
int max = GetSubtitleCount();
if (_ocrMethodIndex == _ocrMethodTesseract && _tesseractAsyncStrings == null)
if (_ocrMethodIndex == _ocrMethodTesseract4 && _tesseractAsyncStrings == null)
{
_tesseractAsyncStrings = new string[max];
_tesseractAsyncIndex = (int)numericUpDownStartNumber.Value + 5;
@ -1484,6 +1486,15 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
if (returnBmp == null)
return null;
if (_ocrMethodIndex == _ocrMethodTesseract4 && !_fromMenuItem)
{
var nb = new NikseBitmap(returnBmp);
nb.AddMargin(2);
nb.MakeTwoColor(Configuration.Settings.Tools.OcrBinaryImageCompareRgbThreshold, Color.White, Color.Black);
returnBmp.Dispose();
return nb.GetBitmap();
}
if (_binaryOcrDb == null && _nOcrDb == null || _fromMenuItem)
{
if (_preprocessingSettings == null || !_preprocessingSettings.Active)
@ -3983,6 +3994,21 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
}
private void ColorLineByNumberOfUnknownWords(int index, int wordsNotFound, string line)
{
SetUnknownWordsColor(index, wordsNotFound, line);
var p = _subtitle.GetParagraphOrDefault(index);
if (p != null && _unknownWordsDictionary.ContainsKey(p.ID))
{
_unknownWordsDictionary[p.ID] = wordsNotFound;
}
else if (p != null)
{
_unknownWordsDictionary.Add(p.ID, wordsNotFound);
}
}
private void SetUnknownWordsColor(int index, int wordsNotFound, string line)
{
if (wordsNotFound >= 3)
subtitleListView1.SetBackgroundColor(index, Color.Red);
@ -3996,16 +4022,6 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
subtitleListView1.SetBackgroundColor(index, Color.Orange);
else
subtitleListView1.SetBackgroundColor(index, Color.LightGreen);
var p = _subtitle.GetParagraphOrDefault(index);
if (p != null && _unknownWordsDictionary.ContainsKey(p.ID))
{
_unknownWordsDictionary[p.ID] = wordsNotFound;
}
else if (p != null)
{
_unknownWordsDictionary.Add(p.ID, wordsNotFound);
}
}
@ -4736,14 +4752,14 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
int wordNonItalics = 0;
bool isItalic = false;
bool allItalic = true;
var seperators = new [] { "-", "—", ".", "'", "\"", " ", "!", "\r", "\n" };
for (int i = 0; i < matches.Count; i++)
{
string text = matches[i].Text;
if (text != null)
{
if (text == "-" || text == "—" || text == "." || text == "'" || text == " " || text == Environment.NewLine)
if (seperators.Contains(text))
{
}
else if (matches[i].Italic)
@ -4766,7 +4782,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
string text = matches[i].Text;
if (text != null)
{
if (text == "-" || text == "—" || text == "." || text == "'" || text == " " || text == Environment.NewLine)
if (seperators.Contains(text))
{
}
else if (matches[i].Italic)
@ -4783,7 +4799,6 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
bool convertAllToNonItalic = lettersNonItalics > 0;
lettersNonItalics = 0;
for (int i = 0; i < matches.Count; i++)
{
string text = matches[i].Text;
@ -4795,9 +4810,9 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
if (convertAllToNonItalic)
italic = false;
if (text == " ")
if (seperators.Contains(text))
{
ItalicsWord(line, ref word, ref lettersItalics, ref lettersNonItalics, ref wordItalics, ref wordNonItalics, ref isItalic, " ");
ItalicsWord(line, ref word, ref lettersItalics, ref lettersNonItalics, ref wordItalics, ref wordNonItalics, ref isItalic, text);
}
else if (text == Environment.NewLine)
{
@ -4810,7 +4825,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
if (!convertAllToItalic && !convertAllToNonItalic)
{
bool isMixedCaseWithoutDashAndAlike = IsMixedCaseWithoutDashAndAlike(matches, i, out var italicOrNot);
if ((text == "-" || text == "—" || text == "." || text == "'") && !isMixedCaseWithoutDashAndAlike)
if (seperators.Contains(text) && !isMixedCaseWithoutDashAndAlike)
{
italic = italicOrNot;
}
@ -5188,18 +5203,21 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
return;
}
if (_ocrMethodIndex == _ocrMethodTesseract302 || _ocrMethodIndex == _ocrMethodTesseract)
if (_ocrMethodIndex == _ocrMethodTesseract302 || _ocrMethodIndex == _ocrMethodTesseract4)
{
labelStatus.Text = Configuration.Settings.Language.General.PleaseWait;
_tesseractThreadRunner?.Cancel();
_tesseractThreadRunner = new TesseractThreadRunner(OcrDone);
_tesseractRunner = new TesseractRunner();
}
if (_ocrMethodIndex == _ocrMethodTesseract && comboBoxTesseractLanguages.Items.Count == 0)
if (_ocrMethodIndex == _ocrMethodTesseract4 && comboBoxTesseractLanguages.Items.Count == 0)
{
buttonGetTesseractDictionaries_Click(sender, e);
return;
}
_mainOcrBitmap = null;
_tesseractEngineMode = comboBoxTesseractEngineMode.SelectedIndex;
_isLatinDb = comboBoxCharacterDatabase.SelectedItem != null && comboBoxCharacterDatabase.SelectedItem.ToString().Equals("Latin", StringComparison.Ordinal);
Configuration.Settings.VobSubOcr.RightToLeft = checkBoxRightToLeft.Checked;
@ -5216,7 +5234,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
listBoxUnknownWords.Items.Clear();
int max = GetSubtitleCount();
if ((_ocrMethodIndex == _ocrMethodTesseract || _ocrMethodIndex == _ocrMethodTesseract302) &&
if ((_ocrMethodIndex == _ocrMethodTesseract4 || _ocrMethodIndex == _ocrMethodTesseract302) &&
_tesseractAsyncStrings == null)
{
_nOcrDb = null;
@ -5498,7 +5516,6 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
}
var bmp = GetSubtitleBitmap(i);
_mainOcrBitmap = bmp;
bool is302 = _ocrMethodIndex == _ocrMethodTesseract302;
_tesseractThreadRunner.AddImageJob(bmp, i, _languageId, string.Empty, _tesseractEngineMode.ToString(CultureInfo.InvariantCulture), is302, is302 && checkBoxTesseractMusicOn.Checked);
_tesseractThreadRunner.CheckQueue();
@ -5507,9 +5524,8 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private void mainOcrTimer_Tick(object sender, EventArgs e)
{
_mainOcrTimer.Stop();
bool done = _ocrMethodIndex == _ocrMethodTesseract || _ocrMethodIndex == _ocrMethodTesseract302 ?
_mainOcrTimer.Stop();
bool done = _ocrMethodIndex == _ocrMethodTesseract4 || _ocrMethodIndex == _ocrMethodTesseract302 ?
MainLoopTesseract(_mainOcrTimerMax, _mainOcrIndex) :
MainLoop(_mainOcrTimerMax, _mainOcrIndex);
if (done || _abort)
@ -5629,6 +5645,16 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
&& (textWithOutFixes.Length < 17 || bitmap.Height < 50))
{
string psm = Tesseract3DoOcrViaExe(bitmap, _languageId, "7", _tesseractEngineMode); // 7 = Treat the image as a single text line.
// sometimes short texts are not recognized - this resize seems to help
if (psm == string.Empty && textWithOutFixes == string.Empty)
{
using (var b = ResizeBitmap(bitmap, bitmap.Width * 2, (int)Math.Round(bitmap.Height * 2.5)))
{
psm = Tesseract3DoOcrViaExe(b, _languageId, string.Empty, _tesseractEngineMode);
}
}
if (textWithOutFixes != psm)
{
if (string.IsNullOrWhiteSpace(textWithOutFixes))
@ -5726,7 +5752,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
checkBoxTesseractFallback.Visible && checkBoxTesseractFallback.Checked)
{
var oldOcrMethodIndex = _ocrMethodIndex;
_ocrMethodIndex = _ocrMethodIndex == _ocrMethodTesseract ? _ocrMethodTesseract302 : _ocrMethodTesseract;
_ocrMethodIndex = _ocrMethodIndex == _ocrMethodTesseract4 ? _ocrMethodTesseract302 : _ocrMethodTesseract4;
newUnfixedText = Tesseract3DoOcrViaExe(bitmap, _languageId, "6", _tesseractEngineMode); // 6 = Assume a single uniform block of text.
newText = _ocrFixEngine.FixOcrErrors(newUnfixedText, index, _lastLine, true, GetAutoGuessLevel());
newWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(newText, out correctWords);
@ -6175,16 +6201,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
if (checkBoxAutoFixCommonErrors.Checked)
line = _ocrFixEngine.FixOcrErrors(line, index, _lastLine, true, GetAutoGuessLevel());
if (badWords >= numberOfWords)
subtitleListView1.SetBackgroundColor(index, Color.Red);
else if (badWords >= numberOfWords / 2)
subtitleListView1.SetBackgroundColor(index, Color.Orange);
else if (badWords > 0 || line.Contains('_') || HasSingleLetters(line))
subtitleListView1.SetBackgroundColor(index, Color.Yellow);
else if (string.IsNullOrWhiteSpace(HtmlUtil.RemoveOpenCloseTags(line, HtmlUtil.TagItalic)))
subtitleListView1.SetBackgroundColor(index, Color.Orange);
else
subtitleListView1.SetBackgroundColor(index, Color.LightGreen);
ColorLineByNumberOfUnknownWords(index, badWords, line);
}
if (textWithOutFixes.Trim() != line.Trim())
@ -6471,6 +6488,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
{
_mainOcrTimer?.Stop();
_abort = true;
_tesseractThreadRunner?.Cancel();
_nocrThreadsStop = true;
buttonStop.Enabled = false;
progressBar1.Visible = false;
@ -6690,15 +6708,33 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private void ComboBoxTesseractLanguagesSelectedIndexChanged(object sender, EventArgs e)
{
Configuration.Settings.VobSubOcr.TesseractLastLanguage = (comboBoxTesseractLanguages.SelectedItem as TesseractLanguage).Id;
var l = (comboBoxTesseractLanguages.SelectedItem as TesseractLanguage).Id;
Configuration.Settings.VobSubOcr.TesseractLastLanguage = l;
_ocrFixEngine?.Dispose();
_ocrFixEngine = null;
LoadOcrFixEngine(null, null);
if (_ocrMethodIndex == _ocrMethodTesseract4)
{
var ok = File.Exists(Path.Combine(Configuration.Tesseract302Directory, "tesseract.exe")) &&
File.Exists(Path.Combine(Configuration.Tesseract302DataDirectory, l + ".traineddata"));
checkBoxTesseractFallback.Visible = ok;
if (!ok)
checkBoxTesseractFallback.Checked = false;
}
else if (_ocrMethodIndex == _ocrMethodTesseract302)
{
var ok = File.Exists(Path.Combine(Configuration.TesseractDirectory, "tesseract.exe")) &&
File.Exists(Path.Combine(Configuration.TesseractDataDirectory, l + ".traineddata"));
checkBoxTesseractFallback.Visible = ok;
if (!ok)
checkBoxTesseractFallback.Checked = false;
}
}
private void LoadOcrFixEngine(string threeLetterIsoLanguageName, string hunspellName)
{
if (_ocrMethodIndex != _ocrMethodTesseract && _ocrMethodIndex != _ocrMethodTesseract302)
if (_ocrMethodIndex != _ocrMethodTesseract4 && _ocrMethodIndex != _ocrMethodTesseract302)
{
try
{
@ -6724,7 +6760,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
string loadedDictionaryName = _ocrFixEngine.SpellCheckDictionaryName;
var found = false;
comboBoxDictionaries.SelectedIndexChanged -= comboBoxDictionaries_SelectedIndexChanged;
if (_ocrMethodIndex == _ocrMethodTesseract &&
if (_ocrMethodIndex == _ocrMethodTesseract4 &&
!string.IsNullOrEmpty(Configuration.Settings.VobSubOcr.LastTesseractSpellCheck) &&
Configuration.Settings.VobSubOcr.LastTesseractSpellCheck.Length > 1 &&
loadedDictionaryName.Length > 1 &&
@ -6775,7 +6811,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
_binaryOcrDb = null;
_nOcrDb = null;
_ocrMethodIndex = comboBoxOcrMethod.SelectedIndex;
if (_ocrMethodIndex == _ocrMethodTesseract)
if (_ocrMethodIndex == _ocrMethodTesseract4)
{
ResetTesseractThread();
InitializeTesseract();
@ -6783,12 +6819,12 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
Configuration.Settings.VobSubOcr.LastOcrMethod = "Tesseract4";
comboBoxTesseractEngineMode.Visible = true;
labelTesseractEngineMode.Visible = true;
checkBoxTesseractFallback.Text = "Fallback to Tesseract 3.02";
checkBoxTesseractFallback.Visible = File.Exists(Path.Combine(Configuration.Tesseract302Directory, "tesseract.exe"));
checkBoxTesseractFallback.Text = string.Format(Configuration.Settings.Language.VobSubOcr.FallbackToX, "Tesseract 3.02");
if (!File.Exists(Path.Combine(Configuration.TesseractDirectory, "tesseract.exe")))
{
if (MessageBox.Show("Download Tesseract 4 Beta", "Subtitle Edit", MessageBoxButtons.YesNoCancel) == DialogResult.Yes)
if (MessageBox.Show("Download Tesseract 4.0.0", "Subtitle Edit", MessageBoxButtons.YesNoCancel) == DialogResult.Yes)
{
comboBoxTesseractLanguages.Items.Clear();
using (var form = new DownloadTesseract4())
{
form.ShowDialog(this);
@ -6809,8 +6845,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
Configuration.Settings.VobSubOcr.LastOcrMethod = "Tesseract302";
comboBoxTesseractEngineMode.Visible = false;
labelTesseractEngineMode.Visible = false;
checkBoxTesseractFallback.Text = "Fallback to Tesseract 4";
checkBoxTesseractFallback.Visible = File.Exists(Path.Combine(Configuration.TesseractDirectory, "tesseract.exe"));
checkBoxTesseractFallback.Text = string.Format(Configuration.Settings.Language.VobSubOcr.FallbackToX, "Tesseract 4.00");
if (!File.Exists(Path.Combine(Configuration.Tesseract302Directory, "tesseract.exe")))
{
if (MessageBox.Show("Download Tesseract 3.02", "Subtitle Edit", MessageBoxButtons.YesNoCancel) == DialogResult.Yes)
@ -7187,7 +7222,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private void comboBoxDictionaries_SelectedIndexChanged(object sender, EventArgs e)
{
Configuration.Settings.General.SpellCheckLanguage = LanguageString;
if (_ocrMethodIndex == _ocrMethodTesseract || _ocrMethodIndex == _ocrMethodTesseract302)
if (_ocrMethodIndex == _ocrMethodTesseract4 || _ocrMethodIndex == _ocrMethodTesseract302)
Configuration.Settings.VobSubOcr.LastTesseractSpellCheck = LanguageString;
string threeLetterIsoLanguageName = string.Empty;
@ -7275,7 +7310,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
else if (Configuration.Settings.VobSubOcr.LastOcrMethod == "Tesseract302" && comboBoxOcrMethod.Items.Count > _ocrMethodTesseract302)
comboBoxOcrMethod.SelectedIndex = _ocrMethodTesseract302;
else if (Configuration.Settings.VobSubOcr.LastOcrMethod == "Tesseract4" && comboBoxOcrMethod.Items.Count > _ocrMethodTesseract302)
comboBoxOcrMethod.SelectedIndex = _ocrMethodTesseract;
comboBoxOcrMethod.SelectedIndex = _ocrMethodTesseract4;
else
comboBoxOcrMethod.SelectedIndex = 0;
}
@ -7735,7 +7770,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
Configuration.Settings.VobSubOcr.LastBinaryImageSpellCheck = comboBoxDictionaries.SelectedItem.ToString();
}
if (_ocrMethodIndex == _ocrMethodTesseract || _ocrMethodTesseract == _ocrMethodTesseract302)
if (_ocrMethodIndex == _ocrMethodTesseract4 || _ocrMethodTesseract4 == _ocrMethodTesseract302)
{
Configuration.Settings.VobSubOcr.LastTesseractSpellCheck = LanguageString;
}
@ -7887,7 +7922,13 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
else
subtitleListView1.SelectIndexAndEnsureVisible(subtitleListView1.Items.Count - 1, true);
_unknownWordsDictionary = new Dictionary<string, int>();
subtitleListView1.BeginUpdate();
foreach (var p in _subtitle.Paragraphs)
{
if (_unknownWordsDictionary.ContainsKey(p.ID))
SetUnknownWordsColor(_subtitle.Paragraphs.IndexOf(p), _unknownWordsDictionary[p.ID], p.Text);
}
subtitleListView1.EndUpdate();
}
private void buttonUknownToNames_Click(object sender, EventArgs e)
@ -8047,6 +8088,22 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
var bmp = GetSubtitleBitmap(_selectedIndex);
_preprocessingSettings = temp;
_fromMenuItem = false;
if (_ocrMethodIndex == _ocrMethodTesseract4)
{
using (var form = new OcrPreprocessingT4(bmp, _ocrMethodIndex == _ocrMethodBinaryImageCompare, new PreprocessingSettings { BinaryImageCompareThresshold = Configuration.Settings.Tools.OcrTesseract4RgbThreshold }))
{
if (form.ShowDialog(this) == DialogResult.OK)
{
ResetTesseractThread();
_preprocessingSettings = form.PreprocessingSettings;
Configuration.Settings.Tools.OcrTesseract4RgbThreshold = _preprocessingSettings.BinaryImageCompareThresshold;
SubtitleListView1SelectedIndexChanged(null, null);
}
}
return;
}
using (var form = new OcrPreprocessingSettings(bmp, _ocrMethodIndex == _ocrMethodBinaryImageCompare, _preprocessingSettings))
{
if (form.ShowDialog(this) == DialogResult.OK)
@ -8301,7 +8358,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private void checkBoxTransportStreamGetColorAndSplit_CheckedChanged(object sender, EventArgs e)
{
if (_ocrMethodIndex == _ocrMethodTesseract)
if (_ocrMethodIndex == _ocrMethodTesseract4)
{
_abort = true;
_nocrThreadsStop = true;

View File

@ -173,7 +173,7 @@
//
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonOK.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonOK.Location = new System.Drawing.Point(329, 365);
this.buttonOK.Location = new System.Drawing.Point(329, 373);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(75, 21);
this.buttonOK.TabIndex = 2;
@ -186,7 +186,7 @@
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonCancel.Location = new System.Drawing.Point(410, 365);
this.buttonCancel.Location = new System.Drawing.Point(410, 373);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 21);
this.buttonCancel.TabIndex = 3;
@ -208,9 +208,9 @@
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pictureBoxSubtitleImage.BackColor = System.Drawing.Color.Transparent;
this.pictureBoxSubtitleImage.Location = new System.Drawing.Point(12, 29);
this.pictureBoxSubtitleImage.Location = new System.Drawing.Point(12, 35);
this.pictureBoxSubtitleImage.Name = "pictureBoxSubtitleImage";
this.pictureBoxSubtitleImage.Size = new System.Drawing.Size(554, 156);
this.pictureBoxSubtitleImage.Size = new System.Drawing.Size(554, 164);
this.pictureBoxSubtitleImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBoxSubtitleImage.TabIndex = 12;
this.pictureBoxSubtitleImage.TabStop = false;
@ -219,7 +219,7 @@
//
this.labelCharactersAsText.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.labelCharactersAsText.AutoSize = true;
this.labelCharactersAsText.Location = new System.Drawing.Point(9, 317);
this.labelCharactersAsText.Location = new System.Drawing.Point(9, 325);
this.labelCharactersAsText.Name = "labelCharactersAsText";
this.labelCharactersAsText.Size = new System.Drawing.Size(105, 13);
this.labelCharactersAsText.TabIndex = 17;
@ -230,7 +230,7 @@
this.textBoxCharacters.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.textBoxCharacters.ContextMenuStrip = this.contextMenuStripLetters;
this.textBoxCharacters.Font = new System.Drawing.Font("Tahoma", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxCharacters.Location = new System.Drawing.Point(12, 333);
this.textBoxCharacters.Location = new System.Drawing.Point(12, 341);
this.textBoxCharacters.Name = "textBoxCharacters";
this.textBoxCharacters.Size = new System.Drawing.Size(225, 27);
this.textBoxCharacters.TabIndex = 0;
@ -918,7 +918,7 @@
// pictureBoxCharacter
//
this.pictureBoxCharacter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.pictureBoxCharacter.Location = new System.Drawing.Point(12, 263);
this.pictureBoxCharacter.Location = new System.Drawing.Point(12, 271);
this.pictureBoxCharacter.Name = "pictureBoxCharacter";
this.pictureBoxCharacter.Size = new System.Drawing.Size(99, 47);
this.pictureBoxCharacter.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
@ -929,7 +929,7 @@
//
this.labelCharacters.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.labelCharacters.AutoSize = true;
this.labelCharacters.Location = new System.Drawing.Point(14, 242);
this.labelCharacters.Location = new System.Drawing.Point(14, 250);
this.labelCharacters.Name = "labelCharacters";
this.labelCharacters.Size = new System.Drawing.Size(68, 13);
this.labelCharacters.TabIndex = 19;
@ -940,7 +940,7 @@
this.buttonAbort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonAbort.DialogResult = System.Windows.Forms.DialogResult.Abort;
this.buttonAbort.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonAbort.Location = new System.Drawing.Point(491, 365);
this.buttonAbort.Location = new System.Drawing.Point(491, 373);
this.buttonAbort.Name = "buttonAbort";
this.buttonAbort.Size = new System.Drawing.Size(75, 21);
this.buttonAbort.TabIndex = 4;
@ -951,7 +951,7 @@
//
this.checkBoxItalic.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.checkBoxItalic.AutoSize = true;
this.checkBoxItalic.Location = new System.Drawing.Point(243, 341);
this.checkBoxItalic.Location = new System.Drawing.Point(243, 349);
this.checkBoxItalic.Name = "checkBoxItalic";
this.checkBoxItalic.Size = new System.Drawing.Size(49, 17);
this.checkBoxItalic.TabIndex = 1;
@ -987,7 +987,7 @@
//
this.buttonLastEdit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonLastEdit.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonLastEdit.Location = new System.Drawing.Point(329, 337);
this.buttonLastEdit.Location = new System.Drawing.Point(329, 345);
this.buttonLastEdit.Name = "buttonLastEdit";
this.buttonLastEdit.Size = new System.Drawing.Size(156, 21);
this.buttonLastEdit.TabIndex = 22;
@ -998,7 +998,7 @@
// pictureBoxLastEdit
//
this.pictureBoxLastEdit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.pictureBoxLastEdit.Location = new System.Drawing.Point(491, 337);
this.pictureBoxLastEdit.Location = new System.Drawing.Point(491, 345);
this.pictureBoxLastEdit.Name = "pictureBoxLastEdit";
this.pictureBoxLastEdit.Size = new System.Drawing.Size(39, 21);
this.pictureBoxLastEdit.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
@ -1009,7 +1009,7 @@
//
this.buttonGuess.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.buttonGuess.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonGuess.Location = new System.Drawing.Point(211, 365);
this.buttonGuess.Location = new System.Drawing.Point(211, 373);
this.buttonGuess.Name = "buttonGuess";
this.buttonGuess.Size = new System.Drawing.Size(112, 21);
this.buttonGuess.TabIndex = 24;
@ -1021,7 +1021,7 @@
//
this.checkBoxAutoSubmitOfFirstChar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.checkBoxAutoSubmitOfFirstChar.AutoSize = true;
this.checkBoxAutoSubmitOfFirstChar.Location = new System.Drawing.Point(12, 372);
this.checkBoxAutoSubmitOfFirstChar.Location = new System.Drawing.Point(12, 380);
this.checkBoxAutoSubmitOfFirstChar.Name = "checkBoxAutoSubmitOfFirstChar";
this.checkBoxAutoSubmitOfFirstChar.Size = new System.Drawing.Size(144, 17);
this.checkBoxAutoSubmitOfFirstChar.TabIndex = 25;
@ -1033,11 +1033,11 @@
//
this.labelItalicOn.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.labelItalicOn.AutoSize = true;
this.labelItalicOn.Font = new System.Drawing.Font("Tahoma", 28F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelItalicOn.Font = new System.Drawing.Font("Tahoma", 24F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelItalicOn.ForeColor = System.Drawing.Color.Red;
this.labelItalicOn.Location = new System.Drawing.Point(193, 1);
this.labelItalicOn.Location = new System.Drawing.Point(193, -1);
this.labelItalicOn.Name = "labelItalicOn";
this.labelItalicOn.Size = new System.Drawing.Size(119, 46);
this.labelItalicOn.Size = new System.Drawing.Size(101, 39);
this.labelItalicOn.TabIndex = 26;
this.labelItalicOn.Text = "Italic";
//
@ -1070,7 +1070,7 @@
this.Column14,
this.Column15});
this.dataGridView1.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this.dataGridView1.Location = new System.Drawing.Point(12, 191);
this.dataGridView1.Location = new System.Drawing.Point(12, 199);
this.dataGridView1.MultiSelect = false;
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.ReadOnly = true;
@ -1237,9 +1237,8 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DimGray;
this.ClientSize = new System.Drawing.Size(577, 396);
this.ClientSize = new System.Drawing.Size(577, 404);
this.Controls.Add(this.dataGridView1);
this.Controls.Add(this.labelItalicOn);
this.Controls.Add(this.checkBoxAutoSubmitOfFirstChar);
this.Controls.Add(this.buttonLastEdit);
this.Controls.Add(this.buttonGuess);
@ -1256,6 +1255,7 @@
this.Controls.Add(this.labelSubtitleImage);
this.Controls.Add(this.pictureBoxSubtitleImage);
this.Controls.Add(this.pictureBoxLastEdit);
this.Controls.Add(this.labelItalicOn);
this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.KeyPreview = true;
this.MaximizeBox = false;

View File

@ -13,7 +13,6 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
{
public sealed partial class VobSubOcrCharacterInspect : Form
{
public XmlDocument ImageCompareDocument { get; private set; }
private List<VobSubOcr.CompareMatch> _matches;
private List<Bitmap> _imageSources;
@ -281,11 +280,14 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private void SetItalic(XmlNode node)
{
if (node?.Attributes == null || node.OwnerDocument == null)
return;
if (checkBoxItalic.Checked)
{
if (node.Attributes["Italic"] == null)
{
XmlAttribute italic = node.OwnerDocument.CreateAttribute("Italic");
var italic = node.OwnerDocument.CreateAttribute("Italic");
italic.InnerText = "true";
node.Attributes.Append(italic);
}
@ -312,6 +314,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
else
_binOcrDb.CompareImages.Remove(_selectedCompareBinaryOcrBitmap);
_selectedCompareBinaryOcrBitmap = null;
_binOcrDb.Save();
}
else
{
@ -326,8 +329,8 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
if (listBoxInspectItems.SelectedIndex < 0)
return;
if (listBoxInspectItems.Items[listBoxInspectItems.SelectedIndex].ToString().Replace(" (italic)", string.Empty) == textBoxText.Text)
{
if (listBoxInspectItems.Items[listBoxInspectItems.SelectedIndex].ToString().Replace(" (italic)", string.Empty) == textBoxText.Text)
{
// text not changed
textBoxText.SelectAll();
textBoxText.Focus();
@ -342,8 +345,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
{
expandCount = _selectedMatch.Extra.Count;
var first = _selectedMatch.Extra[0];
bob = new BinaryOcrBitmap(first.NikseBitmap, checkBoxItalic.Checked, _selectedMatch.Extra.Count, textBoxText.Text, first.X, first.Top);
bob.ExpandedList = new List<BinaryOcrBitmap>();
bob = new BinaryOcrBitmap(first.NikseBitmap, checkBoxItalic.Checked, _selectedMatch.Extra.Count, textBoxText.Text, first.X, first.Top) { ExpandedList = new List<BinaryOcrBitmap>() };
for (int i = 1; i < _selectedMatch.Extra.Count; i++)
{
var element = _selectedMatch.Extra[i];
@ -482,7 +484,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
}
var next = _matches[listBoxInspectItems.SelectedIndex + 1];
if (next.ExpandCount > 0)
if (next.ExpandCount > 0 || next.Extra?.Count > 0)
{
e.Cancel = true;
return;

View File

@ -8,6 +8,7 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace Nikse.SubtitleEdit.Forms
@ -51,8 +52,6 @@ namespace Nikse.SubtitleEdit.Forms
private Main _mainWindow;
private string _currentDictionary;
private static readonly char[] ExpectedChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '%', '&', '@', '$', '*', '=', '£', '#', '_', '½', '^' };
public class SuggestionParameter
{
public string InputWord { get; set; }
@ -524,7 +523,7 @@ namespace Nikse.SubtitleEdit.Forms
if (Configuration.Settings.Tools.SpellCheckOneLetterWords)
minLength = 1;
if (_currentWord.Trim().Length >= minLength && !_currentWord.Contains(ExpectedChars))
if (_currentWord.Trim().Length >= minLength)
{
_prefix = string.Empty;
_postfix = string.Empty;
@ -555,6 +554,10 @@ namespace Nikse.SubtitleEdit.Forms
{
// "skip one" again (after change whole text)
}
else if (IsNumber(_currentWord))
{
_noOfSkippedWords++;
}
else if (_spellCheckWordLists.HasUserWord(_currentWord))
{
_noOfCorrectWords++;
@ -767,10 +770,22 @@ namespace Nikse.SubtitleEdit.Forms
}
}
private static readonly Regex RegexIsNumber = new Regex("^\\d+$", RegexOptions.Compiled);
private static readonly Regex RegexIsEpisodeNumber = new Regex("^\\d+x\\d+$", RegexOptions.Compiled); // e.g. 12x02
private static bool IsNumber(string s)
{
s = s.Trim('$', '£');
if (RegexIsNumber.IsMatch(s))
return true;
if (RegexIsEpisodeNumber.IsMatch(s))
return true;
return false;
}
private void SetWords(string s)
{
s = _spellCheckWordLists.ReplaceHtmlTagsWithBlanks(s);
s = _spellCheckWordLists.ReplaceAssTagsWithBlanks(s);
s = _spellCheckWordLists.ReplaceKnownWordsOrNamesWithBlanks(s);
_words = SpellCheckWordLists.Split(s);
}

View File

@ -12,16 +12,19 @@ namespace Nikse.SubtitleEdit.Logic.Ocr.Tesseract
/// </summary>
public class TesseractMultiRunner
{
private readonly List<string> _tesseractErrors;
public List<string> TesseractErrors { get; set; }
public string LastError { get; set; }
private readonly bool _runningOnWindows;
public TesseractMultiRunner()
{
_tesseractErrors = new List<string>();
TesseractErrors = new List<string>();
_runningOnWindows = !Configuration.IsRunningOnMac() && !Configuration.IsRunningOnLinux();
}
private void TesseractErrorReceived(object sender, DataReceivedEventArgs e)
{
var msg = e.Data;
string msg = e.Data;
if (string.IsNullOrEmpty(msg) ||
msg.StartsWith("Tesseract Open Source OCR Engine", StringComparison.OrdinalIgnoreCase) ||
@ -33,98 +36,99 @@ namespace Nikse.SubtitleEdit.Logic.Ocr.Tesseract
return;
}
_tesseractErrors.Add(msg);
if (TesseractErrors.Count <= 100)
{
if (string.IsNullOrEmpty(LastError))
{
LastError = msg;
}
else if (!LastError.Contains(msg))
{
LastError = LastError + Environment.NewLine + msg;
}
TesseractErrors.Add(msg);
}
}
public string Run(List<NikseBitmap> bmps, string language, string psmMode)
public List<string> Run(string languageCode, string psmMode, string engineMode, List<string> imageFileNames, bool run302 = false)
{
// change yellow color to white - easier for Tesseract
var dir = run302 ? Configuration.Tesseract302Directory : Configuration.TesseractDirectory;
string inputFileName = Path.GetTempPath() + Guid.NewGuid() + ".txt";
var filesToDelete = new List<string>();
var sb = new StringBuilder();
foreach (var bmp in bmps)
foreach (var imageFileName in imageFileNames)
{
bmp.ReplaceYellowWithWhite(); // optimized replace
string pngFileName = Path.GetTempPath() + Guid.NewGuid() + ".png";
using (var b = bmp.GetBitmap())
{
b.Save(pngFileName, System.Drawing.Imaging.ImageFormat.Png);
}
filesToDelete.Add(pngFileName);
sb.AppendLine(pngFileName);
filesToDelete.Add(imageFileName);
sb.AppendLine(imageFileName);
}
File.WriteAllText(inputFileName, sb.ToString());
filesToDelete.Add(inputFileName);
var outputFileName = Path.GetTempPath() + Guid.NewGuid();
var dir = @"C:\Data\SubtitleEdit\subtitleedit\src\bin\Debug\Tesseract4";
using (var process = new Process())
{
process.StartInfo = new ProcessStartInfo(dir + "tesseract.exe")
{
UseShellExecute = true,
Arguments = "\"" + inputFileName + "\" \"" + outputFileName + "\" -l " + language
Arguments = "\"" + inputFileName + "\" \"" + outputFileName + "\" -l " + languageCode
};
if (!string.IsNullOrEmpty(psmMode))
process.StartInfo.Arguments += " " + psmMode.Trim();
{
var prefix = run302 ? " -psm " : " --psm ";
process.StartInfo.Arguments += prefix + psmMode;
}
if (!string.IsNullOrEmpty(engineMode) && !run302)
{
process.StartInfo.Arguments += " --oem " + engineMode;
}
process.StartInfo.Arguments += " hocr";
process.StartInfo.Arguments = " --tessdata-dir \"" + Path.Combine(dir, "tessdata") + "\" " + process.StartInfo.Arguments.Trim();
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (Configuration.IsRunningOnLinux() || Configuration.IsRunningOnMac())
if (_runningOnWindows)
{
if (run302)
{
process.StartInfo.WorkingDirectory = Configuration.Tesseract302Directory;
}
else
{
process.ErrorDataReceived += TesseractErrorReceived;
process.StartInfo.Arguments = " --tessdata-dir \"" + Path.Combine(dir, "tessdata") + "\" " + process.StartInfo.Arguments.Trim();
}
}
else
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.FileName = "tesseract";
}
else
{
var tessdataPath = Path.Combine(Configuration.TesseractDirectory, "tessdata");
process.StartInfo.Arguments = " --tessdata-dir \"" + tessdataPath + "\" " + process.StartInfo.Arguments.Trim();
process.StartInfo.WorkingDirectory = Configuration.TesseractDirectory;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardError = true;
process.ErrorDataReceived += TesseractErrorReceived;
process.EnableRaisingEvents = true;
}
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
try
{
process.Start();
process.BeginErrorReadLine();
}
catch
catch (Exception exception)
{
if (_tesseractErrors.Count <= 2)
{
if (Configuration.IsRunningOnLinux() || Configuration.IsRunningOnMac())
{
_tesseractErrors.Add("Unable to start 'Tesseract' - make sure tesseract-ocr 4.x is installed!");
}
else
{
_tesseractErrors.Add("Unable to start 'Tesseract' (" + Configuration.TesseractDirectory + "tesseract.exe) - make sure Subtitle Edit is install correctly + Visual Studio 2017 C++ runtime");
}
}
LastError = exception.Message + Environment.NewLine + exception.StackTrace;
TesseractErrors.Add(LastError);
return new List<string> { "Error!" };
}
process.WaitForExit(5000 + bmps.Count * 500);
process.WaitForExit(8000 + imageFileNames.Count * 500);
string result = string.Empty;
var result = new List<string>();
string resultFileName = outputFileName + ".html";
if (!File.Exists(outputFileName))
resultFileName = outputFileName + ".hocr";
filesToDelete.Add(resultFileName);
try
{
if (File.Exists(outputFileName))
if (File.Exists(resultFileName))
{
result = File.ReadAllText(outputFileName, Encoding.UTF8);
result = ParseHocr(result);
result = ParseHocr(File.ReadAllText(resultFileName, Encoding.UTF8));
}
foreach (var fileName in filesToDelete)
{
@ -143,45 +147,60 @@ namespace Nikse.SubtitleEdit.Logic.Ocr.Tesseract
}
}
private static string ParseHocr(string html)
internal static List<string> ParseHocr(string html)
{
string s = html.Replace("<em>", "@001_____").Replace("</em>", "@002_____");
int first = s.IndexOf('<');
while (first >= 0)
var pages = new List<string>();
var pageStart = html.IndexOf("<div class='ocr_page'", StringComparison.InvariantCulture);
while (pageStart > 0)
{
int last = s.IndexOf('>');
if (last > 0)
var pageEnd = html.IndexOf("<div class='ocr_page'", pageStart + 1, StringComparison.InvariantCulture);
var sb = new StringBuilder();
var lineStart = html.IndexOf("<span class='ocr_line'", pageStart, StringComparison.InvariantCulture);
while (lineStart > 0 && lineStart < pageEnd)
{
s = s.Remove(first, last - first + 1);
first = s.IndexOf('<');
}
else
{
first = -1;
var wordStart = html.IndexOf("<span class='ocrx_word'", lineStart, StringComparison.InvariantCulture);
int wordMax = html.IndexOf("<span class='ocr_line'", lineStart + 1, StringComparison.InvariantCulture);
if (wordMax <= 0)
wordMax = html.Length;
while (wordStart > 0 && wordStart <= wordMax)
{
var startText = html.IndexOf('>', wordStart + 1);
if (startText > 0)
{
startText++;
var endText = html.IndexOf("</span>", startText + 1, StringComparison.InvariantCulture);
if (endText > 0)
{
var text = html.Substring(startText, endText - startText);
sb.Append(text.Trim() + " ");
}
}
wordStart = html.IndexOf("<span class='ocrx_word'", wordStart + 1, StringComparison.InvariantCulture);
}
sb.AppendLine();
lineStart = html.IndexOf("<span class='ocr_line'", lineStart + 1, StringComparison.InvariantCulture);
}
var page = sb.ToString().Replace("<em>", "<i>").Replace("</em>", "</i>");
page = page.Replace("<strong>", string.Empty).Replace("</strong>", string.Empty);
page = page.Replace("</i> <i>", " ");
page = page.Replace("</i><i>", string.Empty);
// html escape decoding
page = page.Replace("&amp;", "&")
.Replace("&lt;", "<")
.Replace("&gt;", ">")
.Replace("&quot;", "\"")
.Replace("&#39;", "'")
.Replace("&apos;", "'");
page = page.Replace("</i>" + Environment.NewLine + "<i>", Environment.NewLine);
page = page.Replace(" " + Environment.NewLine, Environment.NewLine);
pages.Add(page.Trim());
pageStart = pageEnd;
}
s = s.Trim();
s = s.Replace("@001_____", "<i>").Replace("@002_____", "</i>");
while (s.Contains(" "))
s = s.Replace(" ", " ");
s = s.Replace("</i> <i>", " ");
// html escape decoding
s = s.Replace("&amp;", "&");
s = s.Replace("&lt;", "<");
s = s.Replace("&gt;", ">");
s = s.Replace("&quot;", "\"");
s = s.Replace("&#39;", "'");
s = s.Replace("&apos;", "'");
while (s.Contains("\n\n"))
s = s.Replace("\n\n", "\n");
s = s.Replace("</i>\n<i>", "\n");
s = s.Replace("\n", Environment.NewLine);
return s;
return pages;
}
}

View File

@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
namespace Nikse.SubtitleEdit.Logic.Ocr.Tesseract
{
public class TesseractMultiThreadRunner
{
public delegate void OcrDone(int index, TesseractThreadRunner.ImageJob job);
private readonly OcrDone _callback;
private readonly Queue<TesseractThreadRunner.ImageJob> _jobQueue;
private static readonly object QueueLock = new object();
private readonly TesseractMultiRunner _tesseractRunner;
private bool _abort;
public TesseractMultiThreadRunner(OcrDone callback = null)
{
_jobQueue = new Queue<TesseractThreadRunner.ImageJob>();
_callback = callback;
_tesseractRunner = new TesseractMultiRunner();
_jobs = new List<TesseractThreadRunner.ImageJob>();
}
private void DoOcr(object j)
{
if (_abort)
{
return;
}
var jobs = (List<TesseractThreadRunner.ImageJob>)j;
var job = jobs.First();
var results = _tesseractRunner.Run(job.LanguageCode, job.PsmMode, job.EngineMode, jobs.Select(p=>p.FileName).ToList(), job.Run302);
lock (QueueLock)
{
for (int i = 0; i < jobs.Count; i++)
{
jobs[i].Completed = DateTime.UtcNow;
jobs[i].Result = results.Count - 1 >= i ? results[i] : "MISSING!";
}
job.Completed = DateTime.UtcNow;
}
}
private const int BundleSize = 3;
private List<TesseractThreadRunner.ImageJob> _jobs;
public void AddImageJob(Bitmap bmp, int index, string language, string psmMode, string engineMode, bool run302, bool music302, bool isLast)
{
var job = new TesseractThreadRunner.ImageJob
{
FileName = Path.GetTempFileName() + ".png",
Index = index,
Completed = DateTime.MaxValue,
Bitmap = bmp,
LanguageCode = language + (music302 ? "+music" : string.Empty),
PsmMode = psmMode,
EngineMode = engineMode,
Run302 = run302
};
bmp.Save(job.FileName, System.Drawing.Imaging.ImageFormat.Png);
_jobs.Add(job);
if (_jobs.Count >= BundleSize || isLast)
{
ThreadPool.QueueUserWorkItem(DoOcr, _jobs);
_jobs = new List<TesseractThreadRunner.ImageJob>();
}
_jobQueue.Enqueue(job);
}
public void CheckQueue()
{
if (_jobQueue.Count == 0)
{
return;
}
lock (QueueLock)
{
var checkTime = DateTime.UtcNow;
var job = _jobQueue.Peek();
if (job != null && job.Completed < checkTime)
{
_jobQueue.Dequeue();
_callback?.Invoke(job.Index, job);
}
}
}
public void Cancel()
{
_abort = true;
}
}
}

View File

@ -135,7 +135,7 @@ namespace Nikse.SubtitleEdit.Logic.Ocr.Tesseract
lineStart = html.IndexOf("<span class='ocr_line'", lineStart + 1, StringComparison.InvariantCulture);
}
var result = sb.ToString().Replace("<em>", "<i>").Replace("</em>", "</i>");
result = result.Replace("<strong>", "<i>").Replace("</strong>", "</i>");
result = result.Replace("<strong>", string.Empty).Replace("</strong>", string.Empty);
result = result.Replace("</i> <i>", " ");
result = result.Replace("</i><i>", string.Empty);

View File

@ -42,7 +42,7 @@ namespace Nikse.SubtitleEdit.Logic.Ocr.Tesseract
return;
}
var job = (ImageJob)j;
var job = (ImageJob)j;
job.Result = _tesseractRunner.Run(job.LanguageCode, job.PsmMode, job.EngineMode, job.FileName, job.Run302);
lock (QueueLock)
{
@ -70,7 +70,7 @@ namespace Nikse.SubtitleEdit.Logic.Ocr.Tesseract
public void CheckQueue()
{
if (_jobQueue.Count == 0)
if (_abort || _jobQueue.Count == 0)
{
return;
}
@ -82,7 +82,8 @@ namespace Nikse.SubtitleEdit.Logic.Ocr.Tesseract
if (job != null && job.Completed < checkTime)
{
_jobQueue.Dequeue();
_callback?.Invoke(job.Index, job);
if (!_abort)
_callback?.Invoke(job.Index, job);
}
}
}

View File

@ -44,6 +44,9 @@ namespace Nikse.SubtitleEdit.Logic
return QuartsPlayer.GetVideoInfo(fileName);
}
private static long _lastShowSubTicks = DateTime.UtcNow.Ticks;
private static string _lastShowSubHash;
public static int ShowSubtitle(Subtitle subtitle, VideoPlayerContainer videoPlayerContainer)
{
if (videoPlayerContainer.VideoPlayer != null)
@ -60,19 +63,46 @@ namespace Nikse.SubtitleEdit.Logic
if (!isInfo)
{
if (videoPlayerContainer.LastParagraph != p)
{
videoPlayerContainer.SetSubtitleText(text, p, subtitle);
}
else if (videoPlayerContainer.SubtitleText != text)
{
videoPlayerContainer.SetSubtitleText(text, p, subtitle);
}
TimeOutRefresh(subtitle, videoPlayerContainer, p);
return i;
}
}
}
if (!string.IsNullOrEmpty(videoPlayerContainer.SubtitleText))
{
videoPlayerContainer.SetSubtitleText(string.Empty, null, subtitle);
}
else
{
TimeOutRefresh(subtitle, videoPlayerContainer);
}
}
return -1;
}
private static void TimeOutRefresh(Subtitle subtitle, VideoPlayerContainer videoPlayerContainer, Paragraph p = null)
{
if (DateTime.UtcNow.Ticks - _lastShowSubTicks > 10000 * 1000) // more than 1+ seconds ago
{
var newHash = subtitle.GetFastHashCode(string.Empty);
if (newHash != _lastShowSubHash)
{
videoPlayerContainer.SetSubtitleText(p == null ? string.Empty : p.Text, p, subtitle);
_lastShowSubHash = newHash;
}
_lastShowSubTicks = DateTime.UtcNow.Ticks;
}
}
public static int ShowSubtitle(Subtitle subtitle, Subtitle original, VideoPlayerContainer videoPlayerContainer)
{
if (videoPlayerContainer.VideoPlayer != null)

View File

@ -424,11 +424,8 @@ namespace Nikse.SubtitleEdit.Logic.VideoPlayers
}
_mpvHandle = _mpvCreate.Invoke();
#if DEBUG
var logFileName = Path.Combine(Configuration.DataDirectory, "mpv-log-" + Guid.NewGuid() + ".txt");
_mpvSetOptionString(_mpvHandle, GetUtf8Bytes("log-file"), GetUtf8Bytes(logFileName));
#endif
//var logFileName = Path.Combine(Configuration.DataDirectory, "mpv-log-" + Guid.NewGuid() + ".txt");
//_mpvSetOptionString(_mpvHandle, GetUtf8Bytes("log-file"), GetUtf8Bytes(logFileName));
}
else if (!Directory.Exists(videoFileName))
{

View File

@ -548,6 +548,12 @@
<Compile Include="Forms\Ocr\GetTesseract302Dictionaries.Designer.cs">
<DependentUpon>GetTesseract302Dictionaries.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Ocr\OcrPreprocessingT4.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Ocr\OcrPreprocessingT4.Designer.cs">
<DependentUpon>OcrPreprocessingT4.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Ocr\OcrPreprocessingSettings.cs">
<SubType>Form</SubType>
</Compile>
@ -955,6 +961,7 @@
<Compile Include="Logic\Ocr\NOcrPoint.cs" />
<Compile Include="Logic\Ocr\PreprocessingSettings.cs" />
<Compile Include="Logic\Ocr\SpellCheckOcrTextResult.cs" />
<Compile Include="Logic\Ocr\Tesseract\TesseractMultiThreadRunner.cs" />
<Compile Include="Logic\Ocr\Tesseract\TesseractThreadRunner.cs" />
<Compile Include="Logic\Ocr\Tesseract\TesseractRunner.cs" />
<Compile Include="Logic\Ocr\Tesseract\TesseractMultiRunner.cs" />
@ -1243,6 +1250,9 @@
<EmbeddedResource Include="Forms\Ocr\GetTesseract302Dictionaries.resx">
<DependentUpon>GetTesseract302Dictionaries.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Ocr\OcrPreprocessingT4.resx">
<DependentUpon>OcrPreprocessingT4.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Ocr\OcrPreprocessingSettings.resx">
<DependentUpon>OcrPreprocessingSettings.cs</DependentUpon>
</EmbeddedResource>

View File

@ -2194,5 +2194,51 @@ namespace Test
}
#endregion
#region AddMissingQuotes
[TestMethod]
public void AddMissingQuotesMissingStart()
{
var p = new Paragraph("Bad Ape!\"", 1200, 5000);
var s = new Subtitle();
s.Paragraphs.Add(p);
new AddMissingQuotes().Fix(s, new EmptyFixCallback());
Assert.AreEqual("\"Bad Ape!\"", p.Text);
}
[TestMethod]
public void AddMissingQuotesMissingEnd()
{
var p = new Paragraph("\"Bad Ape!", 1200, 5000);
var s = new Subtitle();
s.Paragraphs.Add(p);
new AddMissingQuotes().Fix(s, new EmptyFixCallback());
Assert.AreEqual("\"Bad Ape!\"", p.Text);
}
[TestMethod]
public void AddMissingQuotesMissingMultiple()
{
var s = new Subtitle();
s.Paragraphs.Add(new Paragraph("\"Bad Ape!", 1200, 5000));
s.Paragraphs.Add(new Paragraph("\"Bad Ape!", 11200, 15000));
s.Paragraphs.Add(new Paragraph("\"Bad Ape!", 21200, 25000));
new AddMissingQuotes().Fix(s, new EmptyFixCallback());
Assert.AreEqual("\"Bad Ape!\"", s.Paragraphs[0].Text);
Assert.AreEqual("\"Bad Ape!\"", s.Paragraphs[1].Text);
Assert.AreEqual("\"Bad Ape!\"", s.Paragraphs[2].Text);
}
[TestMethod]
public void AddMissingQuotesOtherQuote()
{
var p = new Paragraph("\"Bad Ape!”", 1200, 5000);
var s = new Subtitle();
s.Paragraphs.Add(p);
new AddMissingQuotes().Fix(s, new EmptyFixCallback());
Assert.AreEqual("\"Bad Ape!\"", p.Text);
}
#endregion
}
}

View File

@ -79,7 +79,7 @@ namespace Test.Logic
[TestMethod]
public void TestUnknownJsonArray()
{
var raw = @"{
const string raw = @"{
'subtitles': [
{
'sub_order' : 1,
@ -144,5 +144,43 @@ namespace Test.Logic
Assert.AreEqual(11, subtitle.Paragraphs.Count);
Assert.AreEqual("Ford" + Environment.NewLine + "BMW" + Environment.NewLine + "Fiat", subtitle.Paragraphs[1].Text);
}
[TestMethod]
public void ImportBilibiliJson()
{
const string raw = @"{
'body': [
{
'from': 3.7,
'to': 7.7,
'location': 2,
'content': 'Line0'
},
{
'from': 7.7,
'to': 13.7,
'location': 2,
'content': 'Line1'
},
{
'from': 13.7,
'to': 18.7,
'location': 2,
'content': 'Line2'
},
{
'from': 18.7,
'to': 24.7,
'location': 2,
'content': 'Line3'
}]
}";
var importer = new UknownFormatImporterJson();
var subtitle = importer.AutoGuessImport(raw.Replace('\'', '"').SplitToLines());
Assert.AreEqual(4, subtitle.Paragraphs.Count);
Assert.AreEqual("Line1", subtitle.Paragraphs[1].Text);
}
}
}