From 11a23ccfe9fb18a4c516cd5a0b552436e0d49e72 Mon Sep 17 00:00:00 2001 From: "nikse.dk" Date: Fri, 21 Feb 2014 23:10:52 +0100 Subject: [PATCH] Working on ocr --- .gitignore | 1 + src/Controls/SubtitleListView.cs | 59 +++++-- src/Forms/VobSubEditCharacters.Designer.cs | 40 +++-- src/Forms/VobSubEditCharacters.cs | 14 +- src/Forms/VobSubOcr.cs | 166 ++++++++++-------- .../VobSubOcrCharacterInspect.Designer.cs | 13 ++ src/Forms/VobSubOcrCharacterInspect.cs | 44 ++++- src/Forms/VobSubOcrNewFolder.cs | 1 + src/Logic/NikseBitmapImageSplitter.cs | 21 ++- src/Logic/OCR/Binary/BinaryOcrBitmap.cs | 113 +++++++++--- src/Logic/Settings.cs | 4 +- src/SubtitleEdit.sln | 3 - 12 files changed, 344 insertions(+), 135 deletions(-) diff --git a/.gitignore b/.gitignore index 251af7de1..8a4138377 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ /src/Properties/AssemblyInfo.cs /SE*.zip /SubtitleEdit-*-setup.exe +/src/SubtitleEdit.csproj.user diff --git a/src/Controls/SubtitleListView.cs b/src/Controls/SubtitleListView.cs index e76e57a9a..0d99fcbb3 100644 --- a/src/Controls/SubtitleListView.cs +++ b/src/Controls/SubtitleListView.cs @@ -19,9 +19,51 @@ namespace Nikse.SubtitleEdit.Controls private int _firstVisibleIndex = -1; private string _lineSeparatorString = " || "; - public string SubtitleFontName = "Tahoma"; - public bool SubtitleFontBold; - public int SubtitleFontSize = 8; + + private Font _subtitleFont = new Font("Tahoma", 8.25F); + + private string _subtitleFontName = "Tahoma"; + public string SubtitleFontName + { + get { return _subtitleFontName; } + set + { + _subtitleFontName = value; + if (SubtitleFontBold) + _subtitleFont = new System.Drawing.Font(_subtitleFontName, SubtitleFontSize, FontStyle.Bold); + else + _subtitleFont = new System.Drawing.Font(_subtitleFontName, SubtitleFontSize); + } + } + + private bool _subtitleFontBold; + public bool SubtitleFontBold + { + get { return _subtitleFontBold; } + set + { + _subtitleFontBold = value; + if (SubtitleFontBold) + _subtitleFont = new System.Drawing.Font(_subtitleFontName, SubtitleFontSize, FontStyle.Bold); + else + _subtitleFont = new System.Drawing.Font(_subtitleFontName, SubtitleFontSize); + } + } + + private int _subtitleFontSize = 8; + public int SubtitleFontSize + { + get { return _subtitleFontSize; } + set + { + _subtitleFontSize = value; + if (SubtitleFontBold) + _subtitleFont = new System.Drawing.Font(_subtitleFontName, SubtitleFontSize, FontStyle.Bold); + else + _subtitleFont = new System.Drawing.Font(_subtitleFontName, SubtitleFontSize); + } + } + public bool IsAlternateTextColumnVisible { get; private set; } public bool IsExtraColumnVisible { get; private set; } public bool DisplayExtraFromExtra { get; set; } @@ -46,7 +88,7 @@ namespace Nikse.SubtitleEdit.Controls _lineSeparatorString = settings.General.ListViewLineSeparatorString; if (!string.IsNullOrEmpty(settings.General.SubtitleFontName)) - SubtitleFontName = settings.General.SubtitleFontName; + _subtitleFontName = settings.General.SubtitleFontName; SubtitleFontBold = settings.General.SubtitleFontBold; if (settings.General.SubtitleFontSize > 6 && settings.General.SubtitleFontSize < 72) SubtitleFontSize = settings.General.SubtitleFontSize; @@ -159,9 +201,7 @@ namespace Nikse.SubtitleEdit.Controls e.Graphics.FillRectangle(Brushes.LightBlue, rect); } rect = new Rectangle(e.Bounds.Left + 4, e.Bounds.Top+2, e.Bounds.Width - 3, e.Bounds.Height); - Font f = new System.Drawing.Font(SubtitleFontName, SubtitleFontSize, e.Item.Font.Style); - //e.Graphics.DrawString(e.SubItem.Text, f, new SolidBrush(e.Item.ForeColor), rect, sf); - TextRenderer.DrawText(e.Graphics, e.Item.SubItems[e.ColumnIndex].Text, f, new Point(e.Bounds.Left + 3, e.Bounds.Top + 2), e.Item.ForeColor, TextFormatFlags.NoPrefix); + TextRenderer.DrawText(e.Graphics, e.Item.SubItems[e.ColumnIndex].Text, _subtitleFont, new Point(e.Bounds.Left + 3, e.Bounds.Top + 2), e.Item.ForeColor, TextFormatFlags.NoPrefix); } else { @@ -176,7 +216,6 @@ namespace Nikse.SubtitleEdit.Controls { //Rectangle r = new Rectangle(e.Bounds.Left + 1, e.Bounds.Top + 1, e.Bounds.Width - 2, e.Bounds.Height - 2); //e.Graphics.FillRectangle(Brushes.LightGoldenrodYellow, r); - if (e.Item.Focused) e.DrawFocusRectangle(); } @@ -534,9 +573,9 @@ namespace Nikse.SubtitleEdit.Controls subItem = new ListViewItem.ListViewSubItem(item, paragraph.Text.Replace(Environment.NewLine, _lineSeparatorString)); if (SubtitleFontBold) - subItem.Font = new Font(SubtitleFontName, SubtitleFontSize , FontStyle.Bold); + subItem.Font = new Font(_subtitleFontName, SubtitleFontSize , FontStyle.Bold); else - subItem.Font = new Font(SubtitleFontName, SubtitleFontSize); + subItem.Font = new Font(_subtitleFontName, SubtitleFontSize); item.UseItemStyleForSubItems = false; item.SubItems.Add(subItem); diff --git a/src/Forms/VobSubEditCharacters.Designer.cs b/src/Forms/VobSubEditCharacters.Designer.cs index da2a689e9..638ab9b57 100644 --- a/src/Forms/VobSubEditCharacters.Designer.cs +++ b/src/Forms/VobSubEditCharacters.Designer.cs @@ -44,11 +44,12 @@ this.labelImageInfo = new System.Windows.Forms.Label(); this.textBoxText = new System.Windows.Forms.TextBox(); this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.buttonCancel = new System.Windows.Forms.Button(); - this.labelCount = new System.Windows.Forms.Label(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.saveImageAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.labelCount = new System.Windows.Forms.Label(); this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + this.labelExpandCount = new System.Windows.Forms.Label(); this.groupBoxCurrentCompareImage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); @@ -122,6 +123,7 @@ this.groupBoxCurrentCompareImage.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.groupBoxCurrentCompareImage.Controls.Add(this.labelExpandCount); this.groupBoxCurrentCompareImage.Controls.Add(this.checkBoxItalic); this.groupBoxCurrentCompareImage.Controls.Add(this.labelDoubleSize); this.groupBoxCurrentCompareImage.Controls.Add(this.pictureBox2); @@ -214,6 +216,20 @@ this.pictureBox1.TabIndex = 22; this.pictureBox1.TabStop = false; // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.saveImageAsToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(158, 26); + // + // saveImageAsToolStripMenuItem + // + this.saveImageAsToolStripMenuItem.Name = "saveImageAsToolStripMenuItem"; + this.saveImageAsToolStripMenuItem.Size = new System.Drawing.Size(157, 22); + this.saveImageAsToolStripMenuItem.Text = "Save image as..."; + this.saveImageAsToolStripMenuItem.Click += new System.EventHandler(this.saveImageAsToolStripMenuItem_Click); + // // buttonCancel // this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); @@ -236,19 +252,14 @@ this.labelCount.TabIndex = 8; this.labelCount.Text = "labelCount"; // - // contextMenuStrip1 + // labelExpandCount // - this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.saveImageAsToolStripMenuItem}); - this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(158, 48); - // - // saveImageAsToolStripMenuItem - // - this.saveImageAsToolStripMenuItem.Name = "saveImageAsToolStripMenuItem"; - this.saveImageAsToolStripMenuItem.Size = new System.Drawing.Size(157, 22); - this.saveImageAsToolStripMenuItem.Text = "Save image as..."; - this.saveImageAsToolStripMenuItem.Click += new System.EventHandler(this.saveImageAsToolStripMenuItem_Click); + this.labelExpandCount.AutoSize = true; + this.labelExpandCount.Location = new System.Drawing.Point(6, 264); + this.labelExpandCount.Name = "labelExpandCount"; + this.labelExpandCount.Size = new System.Drawing.Size(94, 13); + this.labelExpandCount.TabIndex = 28; + this.labelExpandCount.Text = "labelExpandCount"; // // VobSubEditCharacters // @@ -306,5 +317,6 @@ private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; private System.Windows.Forms.ToolStripMenuItem saveImageAsToolStripMenuItem; private System.Windows.Forms.SaveFileDialog saveFileDialog1; + private System.Windows.Forms.Label labelExpandCount; } } \ No newline at end of file diff --git a/src/Forms/VobSubEditCharacters.cs b/src/Forms/VobSubEditCharacters.cs index 9acf1fee2..adfe20350 100644 --- a/src/Forms/VobSubEditCharacters.cs +++ b/src/Forms/VobSubEditCharacters.cs @@ -27,8 +27,9 @@ namespace Nikse.SubtitleEdit.Forms internal VobSubEditCharacters(string databaseFolderName, List additions, BinaryOcrDb binOcrDb) { - _binOcrDb = binOcrDb; InitializeComponent(); + labelExpandCount.Text = string.Empty; + _binOcrDb = binOcrDb; labelCount.Text = string.Empty; if (additions != null) { @@ -279,13 +280,17 @@ namespace Nikse.SubtitleEdit.Forms string databaseName = _directoryPath + "Images.db"; string posAsString = GetSelectedFileName(); Bitmap bmp = null; - + labelExpandCount.Text = string.Empty; if (_binOcrDb != null) { var bob = GetSelectedBinOcrBitmap(); if (bob != null) { bmp = bob.ToOldBitmap(); + if (bob.ExpandCount > 0) + { + labelExpandCount.Text = string.Format("Expand count: {0}", bob.ExpandCount); + } } } else if (File.Exists(databaseName)) @@ -494,7 +499,10 @@ namespace Nikse.SubtitleEdit.Forms BinaryOcrBitmap bob = GetSelectedBinOcrBitmap(); if (bob != null) { - _binOcrDb.CompareImages.Remove(bob); + if (bob.ExpandCount > 0) + _binOcrDb.CompareImagesExpanded.Remove(bob); + else + _binOcrDb.CompareImages.Remove(bob); if (Additions != null && Additions.Count > 0) { diff --git a/src/Forms/VobSubOcr.cs b/src/Forms/VobSubOcr.cs index f9ba41d78..c91deab82 100644 --- a/src/Forms/VobSubOcr.cs +++ b/src/Forms/VobSubOcr.cs @@ -127,7 +127,10 @@ namespace Nikse.SubtitleEdit.Forms public int ExpandCount { get; set; } public string Name { get; set; } public NOcrChar NOcrCharacter { get; set; } - + public ImageSplitterItem ImageSplitterItem { get; set; } + public int X { get; set; } + public int Y { get; set; } + public CompareMatch(string text, bool italic, int expandCount, string name) { Text = text; @@ -135,16 +138,19 @@ namespace Nikse.SubtitleEdit.Forms ExpandCount = expandCount; Name = name; } - + public CompareMatch(string text, bool italic, int expandCount, string name, NOcrChar character) + : this(text, italic, expandCount, name) { - Text = text; - Italic = italic; - ExpandCount = expandCount; - Name = name; NOcrCharacter = character; } + public CompareMatch(string text, bool italic, int expandCount, string name, ImageSplitterItem imageSplitterItem) + : this(text, italic, expandCount, name) + { + ImageSplitterItem = imageSplitterItem; + } + public override string ToString() { if (Italic) @@ -529,13 +535,15 @@ namespace Nikse.SubtitleEdit.Forms return; } - subtitleListView1.SelectIndexAndEnsureVisible(i); + subtitleListView1.SelectIndexAndEnsureVisible(i); + string text = OcrViaTesseract(GetSubtitleBitmap(i), i); _lastLine = text; text = text.Replace("-", "-"); text = text.Replace("a", "a"); + text = text.Replace(".", "."); text = text.Replace(" ", " "); text = text.Trim(); @@ -2529,59 +2537,58 @@ namespace Nikse.SubtitleEdit.Forms } } - // Search images with minor location changes - FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, target, _binaryOcrDb, bob); - if (maxDiff > 0) - { - if (smallestDifference * 100.0 / (target.Width * target.Height) > _vobSubOcrSettings.AllowDifferenceInPercent && target.Width < 70) - { - if (smallestDifference > 2 && target.Width > 25) - { - var cutBitmap = target.CopyRectangle(new Rectangle(4, 0, target.Width - 4, target.Height)); - FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb, bob); - double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height); - } + FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, target, _binaryOcrDb, bob, maxDiff); + //if (maxDiff > 0.1) + //{ + // if (smallestDifference * 100.0 / (target.Width * target.Height) > _vobSubOcrSettings.AllowDifferenceInPercent && target.Width < 70) + // { + // if (smallestDifference > 2 && target.Width > 25) + // { + // var cutBitmap = target.CopyRectangle(new Rectangle(4, 0, target.Width - 4, target.Height)); + // FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb, new BinaryOcrBitmap(cutBitmap), maxDiff); + // double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height); + // } - if (smallestDifference > 2 && target.Width > 12) - { - var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); - FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb, bob); - } + // if (smallestDifference > 2 && target.Width > 12) + // { + // var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); + // FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb, bob, maxDiff); + // } - if (smallestDifference > 2 && target.Width > 12) - { - var cutBitmap = target.CopyRectangle(new Rectangle(0, 0, target.Width - 2, target.Height)); - FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb, bob); - } + // if (smallestDifference > 2 && target.Width > 12) + // { + // var cutBitmap = target.CopyRectangle(new Rectangle(0, 0, target.Width - 2, target.Height)); + // FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb, bob, maxDiff); + // } - if (smallestDifference > 2 && target.Width > 12) - { - var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); - int topCrop = 0; - var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop, 2); - if (cutBitmap2.Height != target.Height) - FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb, bob); - } + // if (smallestDifference > 2 && target.Width > 12) + // { + // var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); + // int topCrop = 0; + // var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop, 2); + // if (cutBitmap2.Height != target.Height) + // FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb, bob, maxDiff); + // } - if (smallestDifference > 2 && target.Width > 15) - { - var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); - int topCrop = 0; - var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); - if (cutBitmap2.Height != target.Height) - FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb, bob); - } + // if (smallestDifference > 2 && target.Width > 15) + // { + // var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); + // int topCrop = 0; + // var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); + // if (cutBitmap2.Height != target.Height) + // FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb, bob, maxDiff); + // } - if (smallestDifference > 2 && target.Width > 15) - { - var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); - int topCrop = 0; - var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); - if (cutBitmap2.Height != target.Height) - FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb, bob); - } - } - } + // if (smallestDifference > 2 && target.Width > 15) + // { + // var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); + // int topCrop = 0; + // var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); + // if (cutBitmap2.Height != target.Height) + // FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb, bob, maxDiff); + // } + // } + //} if (smallestIndex >= 0) { @@ -2630,7 +2637,7 @@ namespace Nikse.SubtitleEdit.Forms return bmp; } - private static void FindBestMatchNew(ref int index, ref int smallestDifference, ref int smallestIndex, NikseBitmap target, BinaryOcrDb binOcrDb, BinaryOcrBitmap bob) + private static void FindBestMatchNew(ref int index, ref int smallestDifference, ref int smallestIndex, NikseBitmap target, BinaryOcrDb binOcrDb, BinaryOcrBitmap bob, double maxDiff) { var bobExactMatch = binOcrDb.FindExactMatch(bob); if (bobExactMatch >= 0) @@ -2639,7 +2646,10 @@ namespace Nikse.SubtitleEdit.Forms smallestDifference = 0; smallestIndex = bobExactMatch; return; - } + } + + if (maxDiff < 0.2) + return; int numberOfForegroundColors = bob.NumberOfColoredPixels; int minForeColorMatch = 90; @@ -2828,7 +2838,7 @@ namespace Nikse.SubtitleEdit.Forms } } - if (smallestDifference > 9 && target.Width > 10) + if (smallestDifference > 9 && target.Width > 11) { index = 0; foreach (var compareItem in binOcrDb.CompareImages) @@ -2851,7 +2861,7 @@ namespace Nikse.SubtitleEdit.Forms } } - if (smallestDifference > 9 && target.Width > 12) + if (smallestDifference > 9 && target.Width > 14) { index = 0; foreach (var compareItem in binOcrDb.CompareImages) @@ -2874,7 +2884,7 @@ namespace Nikse.SubtitleEdit.Forms } } - if (smallestDifference > 9 && target.Width > 12) + if (smallestDifference > 9 && target.Width > 14) { index = 0; foreach (var compareItem in binOcrDb.CompareImages) @@ -2897,7 +2907,7 @@ namespace Nikse.SubtitleEdit.Forms } } - if (smallestDifference > 9) + if (smallestDifference > 9 && target.Width > 14) { index = 0; foreach (var compareItem in binOcrDb.CompareImages) @@ -3343,7 +3353,7 @@ namespace Nikse.SubtitleEdit.Forms return name; } - private string SaveCompareItemNew(NikseBitmap newTarget, string text, bool isItalic, List expandList) + private string SaveCompareItemNew(ImageSplitterItem newTarget, string text, bool isItalic, List expandList) { int expandCount = 0; if (expandList != null) @@ -3351,17 +3361,22 @@ namespace Nikse.SubtitleEdit.Forms if (expandCount > 0) { - var bob = new BinaryOcrBitmap(expandList[0].NikseBitmap, isItalic, expandCount, text); + var bob = new BinaryOcrBitmap(expandList[0].NikseBitmap, isItalic, expandCount, text, expandList[0].X, expandList[0].Y); bob.ExpandedList = new List(); for (int j = 1; j < expandList.Count; j++) - bob.ExpandedList.Add(new BinaryOcrBitmap(expandList[j].NikseBitmap)); + { + var expandedBob = new BinaryOcrBitmap(expandList[j].NikseBitmap); + expandedBob.X = expandList[j].X; + expandedBob.Y = expandList[j].Y; + bob.ExpandedList.Add(expandedBob); + } _binaryOcrDb.Add(bob); _binaryOcrDb.Save(); return bob.Key; } else { - var bob = new BinaryOcrBitmap(newTarget, isItalic, expandCount, text); + var bob = new BinaryOcrBitmap(newTarget.NikseBitmap, isItalic, expandCount, text, newTarget.X, newTarget.Y); _binaryOcrDb.Add(bob); _binaryOcrDb.Save(); return bob.Key; @@ -3623,7 +3638,7 @@ namespace Nikse.SubtitleEdit.Forms else if (result == DialogResult.OK) { string text = _vobSubOcrCharacter.ManualRecognizedCharacters; - string name = SaveCompareItemNew(item.NikseBitmap, text, _vobSubOcrCharacter.IsItalic, expandSelectionList); + string name = SaveCompareItemNew(item, text, _vobSubOcrCharacter.IsItalic, expandSelectionList); var addition = new ImageCompareAddition(name, text, item.NikseBitmap, _vobSubOcrCharacter.IsItalic, listViewIndex); _lastAdditions.Add(addition); matches.Add(new CompareMatch(text, _vobSubOcrCharacter.IsItalic, expandSelectionList.Count, null)); @@ -3661,7 +3676,7 @@ namespace Nikse.SubtitleEdit.Forms else if (result == DialogResult.OK) { string text = _vobSubOcrCharacter.ManualRecognizedCharacters; - string name = SaveCompareItemNew(item.NikseBitmap, text, _vobSubOcrCharacter.IsItalic, null); + string name = SaveCompareItemNew(item, text, _vobSubOcrCharacter.IsItalic, null); var addition = new ImageCompareAddition(name, text, item.NikseBitmap, _vobSubOcrCharacter.IsItalic, listViewIndex); _lastAdditions.Add(addition); matches.Add(new CompareMatch(text, _vobSubOcrCharacter.IsItalic, 0, null)); @@ -4661,6 +4676,7 @@ namespace Nikse.SubtitleEdit.Forms _mainOcrRunning = false; labelStatus.Text = string.Empty; progressBar1.Visible = false; + subtitleListView1.MultiSelect = true; } static void ImageCompareThreadDoWork(object sender, DoWorkEventArgs e) @@ -5185,6 +5201,7 @@ namespace Nikse.SubtitleEdit.Forms _mainOcrTimer.Tick += mainOcrTimer_Tick; _mainOcrTimer.Interval = 5; _mainOcrRunning = true; + subtitleListView1.MultiSelect = false; mainOcrTimer_Tick(null, null); if (comboBoxOcrMethod.SelectedIndex == 1) @@ -5237,7 +5254,15 @@ namespace Nikse.SubtitleEdit.Forms } _mainOcrBitmap = bmp; - subtitleListView1.SelectIndexAndEnsureVisible(i); + + int j = i; + subtitleListView1.Items[j].Selected = true; + if (j < max -1) + j++; + if (j < max - 1) + j++; + subtitleListView1.Items[j].EnsureVisible(); + string text = string.Empty; if (comboBoxOcrMethod.SelectedIndex == 0) text = OcrViaTesseract(bmp, i); @@ -5254,6 +5279,7 @@ namespace Nikse.SubtitleEdit.Forms text = text.Replace("-", "-"); text = text.Replace("a", "a"); + text = text.Replace(".", "."); text = text.Replace(" ", " "); text = text.Trim(); @@ -7311,12 +7337,12 @@ namespace Nikse.SubtitleEdit.Forms expandSelectionList.Add(list[index + i]); } item = GetExpandedSelectionNew(parentBitmap, expandSelectionList); - matches.Add(new CompareMatch(match.Text, match.Italic, 0, match.Name)); + matches.Add(new CompareMatch(match.Text, match.Italic, 0, match.Name, item)); imageSources.Add(item.NikseBitmap.GetBitmap()); } else { - matches.Add(new CompareMatch(match.Text, match.Italic, 0, match.Name)); + matches.Add(new CompareMatch(match.Text, match.Italic, 0, match.Name, item)); imageSources.Add(item.NikseBitmap.GetBitmap()); } diff --git a/src/Forms/VobSubOcrCharacterInspect.Designer.cs b/src/Forms/VobSubOcrCharacterInspect.Designer.cs index f9e6d9025..61b89163a 100644 --- a/src/Forms/VobSubOcrCharacterInspect.Designer.cs +++ b/src/Forms/VobSubOcrCharacterInspect.Designer.cs @@ -44,6 +44,7 @@ this.listBoxInspectItems = new System.Windows.Forms.ListBox(); this.groupBoxInspectItems = new System.Windows.Forms.GroupBox(); this.pictureBoxInspectItem = new System.Windows.Forms.PictureBox(); + this.labelExpandCount = new System.Windows.Forms.Label(); this.groupBoxCurrentCompareImage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCompareBitmapDouble)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCompareBitmap)).BeginInit(); @@ -208,6 +209,7 @@ // this.groupBoxInspectItems.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); + this.groupBoxInspectItems.Controls.Add(this.labelExpandCount); this.groupBoxInspectItems.Controls.Add(this.pictureBoxInspectItem); this.groupBoxInspectItems.Controls.Add(this.listBoxInspectItems); this.groupBoxInspectItems.Location = new System.Drawing.Point(12, 12); @@ -226,6 +228,15 @@ this.pictureBoxInspectItem.TabIndex = 23; this.pictureBoxInspectItem.TabStop = false; // + // labelExpandCount + // + this.labelExpandCount.AutoSize = true; + this.labelExpandCount.Location = new System.Drawing.Point(252, 98); + this.labelExpandCount.Name = "labelExpandCount"; + this.labelExpandCount.Size = new System.Drawing.Size(93, 13); + this.labelExpandCount.TabIndex = 29; + this.labelExpandCount.Text = "labelExpandCount"; + // // VobSubOcrCharacterInspect // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -248,6 +259,7 @@ ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCompareBitmapDouble)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCompareBitmap)).EndInit(); this.groupBoxInspectItems.ResumeLayout(false); + this.groupBoxInspectItems.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBoxInspectItem)).EndInit(); this.ResumeLayout(false); @@ -271,5 +283,6 @@ private System.Windows.Forms.GroupBox groupBoxInspectItems; private System.Windows.Forms.PictureBox pictureBoxInspectItem; private System.Windows.Forms.Button buttonAddBetterMatch; + private System.Windows.Forms.Label labelExpandCount; } } \ No newline at end of file diff --git a/src/Forms/VobSubOcrCharacterInspect.cs b/src/Forms/VobSubOcrCharacterInspect.cs index 4b5f740c5..be896b3f2 100644 --- a/src/Forms/VobSubOcrCharacterInspect.cs +++ b/src/Forms/VobSubOcrCharacterInspect.cs @@ -19,12 +19,14 @@ namespace Nikse.SubtitleEdit.Forms private string _directoryPath; private XmlNode _selectedCompareNode = null; private BinaryOcrBitmap _selectedCompareBinaryOcrBitmap = null; + private VobSubOcr.CompareMatch _selectedMatch = null; BinaryOcrDb _binOcrDb = null; public VobSubOcrCharacterInspect() { InitializeComponent(); + labelExpandCount.Text = string.Empty; Text = Configuration.Settings.Language.VobSubOcrCharacterInspect.Title; groupBoxInspectItems.Text = Configuration.Settings.Language.VobSubOcrCharacterInspect.InspectItems; labelImageInfo.Text = string.Empty; @@ -76,24 +78,28 @@ namespace Nikse.SubtitleEdit.Forms private void listBoxInspectItems_SelectedIndexChanged(object sender, EventArgs e) { labelImageInfo.Text = string.Empty; + labelExpandCount.Text = string.Empty; if (listBoxInspectItems.SelectedIndex < 0) return; _selectedCompareNode = null; _selectedCompareBinaryOcrBitmap = null; + pictureBoxInspectItem.Image = _imageSources[listBoxInspectItems.SelectedIndex]; pictureBoxCompareBitmap.Image = null; pictureBoxCompareBitmapDouble.Image = null; int index = (listBoxInspectItems.SelectedIndex); var match = _matches[index]; + _selectedMatch = match; if (!string.IsNullOrEmpty(match.Name)) { Bitmap bitmap = new Bitmap(1,1); if (_binOcrDb != null) { + bool bobFound = false; foreach (BinaryOcrBitmap bob in _binOcrDb.CompareImages) { if (match.Name == bob.Key) @@ -117,9 +123,33 @@ namespace Nikse.SubtitleEdit.Forms { buttonAddBetterMatch.Enabled = true; } + + bobFound = true; break; } } + if (!bobFound) + { + foreach (BinaryOcrBitmap bob in _binOcrDb.CompareImagesExpanded) + { + if (match.Name == bob.Key) + { + textBoxText.Text = bob.Text; + checkBoxItalic.Checked = bob.Italic; + _selectedCompareBinaryOcrBitmap = bob; + + bitmap = bob.ToOldBitmap(); + pictureBoxCompareBitmap.Image = bitmap; + pictureBoxCompareBitmapDouble.Width = bitmap.Width * 2; + pictureBoxCompareBitmapDouble.Height = bitmap.Height * 2; + pictureBoxCompareBitmapDouble.Image = bitmap; + var matchBob = new BinaryOcrBitmap(new NikseBitmap(_imageSources[listBoxInspectItems.SelectedIndex])); + buttonAddBetterMatch.Enabled = false; // exact match + labelExpandCount.Text = string.Format("Expand count: {0}", bob.ExpandCount); + break; + } + } + } } else { @@ -260,7 +290,10 @@ namespace Nikse.SubtitleEdit.Forms listBoxInspectItems.Items[listBoxInspectItems.SelectedIndex] = Configuration.Settings.Language.VobSubOcr.NoMatch; if (_selectedCompareBinaryOcrBitmap != null) { - _binOcrDb.CompareImages.Remove(_selectedCompareBinaryOcrBitmap); + if (_selectedCompareBinaryOcrBitmap.ExpandCount > 0) + _binOcrDb.CompareImagesExpanded.Remove(_selectedCompareBinaryOcrBitmap); + else + _binOcrDb.CompareImages.Remove(_selectedCompareBinaryOcrBitmap); _selectedCompareBinaryOcrBitmap = null; } else @@ -332,7 +365,14 @@ namespace Nikse.SubtitleEdit.Forms else if (_selectedCompareBinaryOcrBitmap != null) { var nbmp = new NikseBitmap((pictureBoxInspectItem.Image as Bitmap)); - BinaryOcrBitmap bob = new BinaryOcrBitmap(nbmp, checkBoxItalic.Checked, 0, textBoxText.Text); + int x = 0; + int y = 0; + if (_selectedMatch != null && _selectedMatch.ImageSplitterItem != null) + { + x = _selectedMatch.X; + y = _selectedMatch.Y; + } + var bob = new BinaryOcrBitmap(nbmp, checkBoxItalic.Checked, 0, textBoxText.Text, x, y); _binOcrDb.Add(bob); int index = listBoxInspectItems.SelectedIndex; diff --git a/src/Forms/VobSubOcrNewFolder.cs b/src/Forms/VobSubOcrNewFolder.cs index fb195b814..5b1b21a7d 100644 --- a/src/Forms/VobSubOcrNewFolder.cs +++ b/src/Forms/VobSubOcrNewFolder.cs @@ -59,6 +59,7 @@ namespace Nikse.SubtitleEdit.Forms if (!_vobSub) { + FolderName = folderName; DialogResult = DialogResult.OK; return; } diff --git a/src/Logic/NikseBitmapImageSplitter.cs b/src/Logic/NikseBitmapImageSplitter.cs index ac3e1b3e9..650d2c2e1 100644 --- a/src/Logic/NikseBitmapImageSplitter.cs +++ b/src/Logic/NikseBitmapImageSplitter.cs @@ -728,6 +728,7 @@ namespace Nikse.SubtitleEdit.Logic private static List IsVerticalLineTransparetNew(NikseBitmap bmp, int x, out bool right, out bool clean) { right = false; + bool left = false; clean = true; var points = new List(); int y = 0; @@ -749,29 +750,39 @@ namespace Nikse.SubtitleEdit.Logic } else if (x > 0 && bmp.GetAlpha(x - 1, y) == 0) { - x--; //(requires search for min/max x in points + x--; //(requires search for min/max x in points + left = true; } else + { return null; + } } else if (x < bmp.Width - 1 && y == bmp.Height - 1 && bmp.GetAlpha(x + 1, y) == 0 && bmp.GetAlpha(x + 1, y - 1) == 0) { //if pixels to the left - move right? if (bmp.GetAlpha(x - 1, y) > 0) + { x++; //(requires search for min/max x in points + right = true; + } else + { return null; + } right = true; } else if (bmp.GetAlpha(x - 1, y) == 0) { x--; + left = true; } else if (y > 5 && bmp.GetAlpha(x - 1, y - 1) == 0) { x--; y--; + left = true; while (points.Count > 0 && points[points.Count - 1].Y > y) points.RemoveAt(points.Count - 1); } @@ -779,6 +790,7 @@ namespace Nikse.SubtitleEdit.Logic { x--; y -= 2; + left = true; while (points.Count > 0 && points[points.Count - 1].Y > y) points.RemoveAt(points.Count - 1); } @@ -786,6 +798,9 @@ namespace Nikse.SubtitleEdit.Logic { return null; } + + if (left && right) + return null; } else { @@ -889,7 +904,7 @@ namespace Nikse.SubtitleEdit.Logic for (int y = 1; y < bmp1.Height; y++) { //if (!IsColorClose(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20)) - if (bmp1.GetPixel(x, y) && bmp2.GetAlpha(x, y) < 100) + if (bmp1.GetPixel(x, y) > 0 && bmp2.GetAlpha(x, y) < 100) different++; } if (different > maxDiff) @@ -907,7 +922,7 @@ namespace Nikse.SubtitleEdit.Logic { for (int y = 1; y < bmp1.Height; y++) { - if (bmp1.GetAlpha(x, y) < 100 && bmp2.GetPixel(x, y)) + if (bmp1.GetAlpha(x, y) < 100 && bmp2.GetPixel(x, y) > 0) different++; } if (different > maxDiff) diff --git a/src/Logic/OCR/Binary/BinaryOcrBitmap.cs b/src/Logic/OCR/Binary/BinaryOcrBitmap.cs index 571102275..963c0e627 100644 --- a/src/Logic/OCR/Binary/BinaryOcrBitmap.cs +++ b/src/Logic/OCR/Binary/BinaryOcrBitmap.cs @@ -12,6 +12,8 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary //------------- //2bytes=width //2bytes=height + //2bytes=x + //2bytes=y //2bytes=numberOfColoredPixels //1byte=flags (1 bit = italic, next 7 bits = ExpandCount) //4bytes=hash @@ -21,6 +23,8 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary public int Width { get; private set; } public int Height { get; private set; } + public int X { get; set; } + public int Y { get; set; } public int NumberOfColoredPixels { get; private set; } public UInt32 Hash { get; private set; } private byte[] _colors; @@ -45,11 +49,20 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary return Text + " (" + Width + "x" + Height + ")"; } + public BinaryOcrBitmap(int width, int height) + { + Width = width; + Height = height; + _colors = new byte[Width * Height]; + Hash = MurMurHash3.Hash(_colors); + CalcuateNumberOfColoredPixels(); + } + public BinaryOcrBitmap(Stream stream) { try { - byte[] buffer = new byte[12]; + byte[] buffer = new byte[16]; int read = stream.Read(buffer, 0, buffer.Length); if (read < buffer.Length) { @@ -58,11 +71,13 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary } Width = buffer[0] << 8 | buffer[1]; Height = buffer[2] << 8 | buffer[3]; - NumberOfColoredPixels = buffer[4] << 8 | buffer[5]; - Italic = (buffer[6] & Nikse.SubtitleEdit.Logic.VobSub.Helper.B10000000) > 0; - ExpandCount = buffer[6] & Nikse.SubtitleEdit.Logic.VobSub.Helper.B01111111; - Hash = (uint)(buffer[7] << 24 | buffer[8] << 16 | buffer[9] << 8 | buffer[10]); - int textLen = buffer[11]; + X = buffer[4] << 8 | buffer[5]; + Y = buffer[6] << 8 | buffer[7]; + NumberOfColoredPixels = buffer[8] << 8 | buffer[9]; + Italic = (buffer[10] & Nikse.SubtitleEdit.Logic.VobSub.Helper.B10000000) > 0; + ExpandCount = buffer[10] & Nikse.SubtitleEdit.Logic.VobSub.Helper.B01111111; + Hash = (uint)(buffer[11] << 24 | buffer[12] << 16 | buffer[13] << 8 | buffer[14]); + int textLen = buffer[15]; if (textLen > 0) { buffer = new byte[textLen]; @@ -85,12 +100,14 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary InitializeViaNikseBmp(nbmp); } - public BinaryOcrBitmap(NikseBitmap nbmp, bool italic, int expandCount, string text) + public BinaryOcrBitmap(NikseBitmap nbmp, bool italic, int expandCount, string text, int x, int y) { InitializeViaNikseBmp(nbmp); Italic = italic; ExpandCount = expandCount; Text = text; + X = x; + Y = y; } private void InitializeViaNikseBmp(NikseBitmap nbmp) @@ -124,6 +141,9 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary WriteInt16(stream, (short)Width); WriteInt16(stream, (short)Height); + WriteInt16(stream, (short)X); + WriteInt16(stream, (short)Y); + WriteInt16(stream, (short)NumberOfColoredPixels); byte flags = (byte)(ExpandCount & Nikse.SubtitleEdit.Logic.VobSub.Helper.B01111111); @@ -147,14 +167,7 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary stream.Write(_colors, 0, _colors.Length); } - private int ReadInt16(Stream stream) - { - byte b0 = (byte)stream.ReadByte(); - byte b1 = (byte)stream.ReadByte(); - return b0 << 8 | b1; - } - - private void WriteInt16(Stream stream, short val) + private static void WriteInt16(Stream stream, short val) { byte[] buffer = new byte[2]; buffer[0] = (byte)((val & 0xFF00) >> 8); @@ -162,7 +175,7 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary stream.Write(buffer, 0, buffer.Length); } - private void WriteInt32(Stream stream, UInt32 val) + private static void WriteInt32(Stream stream, UInt32 val) { System.ComponentModel.ByteConverter bc = new System.ComponentModel.ByteConverter(); @@ -173,10 +186,15 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary buffer[3] = (byte)(val & 0xFF); stream.Write(buffer, 0, buffer.Length); } - - public bool GetPixel(int x, int y) + + public int GetPixel(int x, int y) { - return _colors[Width * y + x] > 0; + return _colors[Width * y + x]; + } + + public void SetPixel(int x, int y, int c) + { + _colors[Width * y + x] = (byte)c; } public void SetPixel(int x, int y, Color c) @@ -203,7 +221,7 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary for (int x = section.Left; x < section.Left + section.Width; x++) { Color c = Color.Transparent; - if (this.GetPixel(x, y)) + if (this.GetPixel(x, y) > 0) c = Color.White; newRectangle.SetPixel(rectx, recty, c); rectx++; @@ -215,18 +233,57 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary public Bitmap ToOldBitmap() { - var nbmp = new NikseBitmap(Width, Height); - for (int y = 0; y < Height; y++) + if (ExpandedList != null && ExpandedList.Count > 0) { - for (int x = 0; x < Width; x++) + int minX = X; + int minY = Y; + int maxX = X + Width; + int maxY = Y + Height; + var list = new List(); + list.Add(this); + foreach (BinaryOcrBitmap bob in ExpandedList) { - Color c = Color.Transparent; - if (this.GetPixel(x, y)) - c = Color.White; - nbmp.SetPixel(x, y, c); + if (bob.X < minX) + minX = bob.X; + if (bob.Y < minY) + minY = bob.Y; + if (bob.X + bob.Width > maxX) + maxX = bob.X + bob.Width; + if (bob.Y + bob.Height > maxY) + maxY = bob.Y + bob.Height; + list.Add(bob); } + var nbmp = new BinaryOcrBitmap(maxX - minX, maxY - minY); + foreach (BinaryOcrBitmap bob in list) + { + for (int y = 0; y < bob.Height; y++) + { + for (int x = 0; x < bob.Width; x++) + { + int c = bob.GetPixel(x, y); + if (c > 0) + nbmp.SetPixel(bob.X - minX + x, bob.Y - minY + y, 1); + } + } + } + + return nbmp.ToOldBitmap(); // Resursive + } + else + { + var nbmp = new NikseBitmap(Width, Height); + for (int y = 0; y < Height; y++) + { + for (int x = 0; x < Width; x++) + { + Color c = Color.Transparent; + if (this.GetPixel(x, y) > 0) + c = Color.White; + nbmp.SetPixel(x, y, c); + } + } + return nbmp.GetBitmap(); } - return nbmp.GetBitmap(); } internal void DrawImage(ManagedBitmap bmp, Point point) diff --git a/src/Logic/Settings.cs b/src/Logic/Settings.cs index 33ce6fcfe..1e32ec650 100644 --- a/src/Logic/Settings.cs +++ b/src/Logic/Settings.cs @@ -1178,7 +1178,7 @@ namespace Nikse.SubtitleEdit.Logic subNode = node.SelectSingleNode("AutoGuessAnsiEncoding"); if (subNode != null) settings.General.AutoGuessAnsiEncoding = Convert.ToBoolean(subNode.InnerText); - subNode = node.SelectSingleNode("SubtitleFontName"); + subNode = node.SelectSingleNode("_subtitleFontName"); if (subNode != null) settings.General.SubtitleFontName = subNode.InnerText; subNode = node.SelectSingleNode("SubtitleFontSize"); @@ -2476,7 +2476,7 @@ namespace Nikse.SubtitleEdit.Logic textWriter.WriteElementString("DefaultEncoding", settings.General.DefaultEncoding); textWriter.WriteElementString("AutoConvertToUtf8", settings.General.AutoConvertToUtf8.ToString()); textWriter.WriteElementString("AutoGuessAnsiEncoding", settings.General.AutoGuessAnsiEncoding.ToString()); - textWriter.WriteElementString("SubtitleFontName", settings.General.SubtitleFontName); + textWriter.WriteElementString("_subtitleFontName", settings.General.SubtitleFontName); textWriter.WriteElementString("SubtitleFontSize", settings.General.SubtitleFontSize.ToString()); textWriter.WriteElementString("SubtitleFontBold", settings.General.SubtitleFontBold.ToString()); textWriter.WriteElementString("SubtitleFontColor", settings.General.SubtitleFontColor.ToArgb().ToString()); diff --git a/src/SubtitleEdit.sln b/src/SubtitleEdit.sln index 9b58a8ebe..0e9df2e40 100644 --- a/src/SubtitleEdit.sln +++ b/src/SubtitleEdit.sln @@ -41,7 +41,4 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection EndGlobal