public void TestMethodBinOcrSaveLoad()
        {
            string tempFileName = Path.GetTempFileName();
            var db = new BinaryOcrDb(tempFileName);
            var nbmp = new NikseBitmap(2, 2);
            nbmp.SetPixel(0, 0, Color.Transparent);
            nbmp.SetPixel(1, 0, Color.Transparent);
            nbmp.SetPixel(1, 0, Color.Transparent);
            nbmp.SetPixel(1, 1, Color.White);

            var bob = new BinaryOcrBitmap(nbmp);
            bob.Text = "Debug";
            db.Add(bob);

            nbmp.SetPixel(0, 0, Color.White);
            var bob2 = new BinaryOcrBitmap(nbmp);
            bob2.X = 2;
            bob2.Y = 4;
            bob2.Text = "tt";
            bob2.Italic = true;
            bob2.ExpandCount = 2;
            bob2.ExpandedList = new System.Collections.Generic.List<BinaryOcrBitmap>();
            bob2.ExpandedList.Add(bob2);
            db.Add(bob2);
            db.Save();

            db = new BinaryOcrDb(tempFileName, true);
            Assert.IsTrue(db.CompareImages.Count == 1);
            Assert.IsTrue(db.CompareImagesExpanded.Count == 1);

            Assert.IsTrue(bob.Width == db.CompareImages[0].Width);
            Assert.IsTrue(bob.Height == db.CompareImages[0].Height);
            Assert.IsTrue(bob.NumberOfColoredPixels == db.CompareImages[0].NumberOfColoredPixels);
            Assert.IsTrue(bob.Hash == db.CompareImages[0].Hash);
            Assert.IsTrue(bob.Italic == db.CompareImages[0].Italic);
            Assert.IsTrue(bob.ExpandCount == db.CompareImages[0].ExpandCount);
            Assert.IsTrue(bob.Text == db.CompareImages[0].Text);

            Assert.IsTrue(bob2.Width == db.CompareImagesExpanded[0].Width);
            Assert.IsTrue(bob2.Height == db.CompareImagesExpanded[0].Height);
            Assert.IsTrue(bob2.NumberOfColoredPixels == db.CompareImagesExpanded[0].NumberOfColoredPixels);
            Assert.IsTrue(bob2.Hash == db.CompareImagesExpanded[0].Hash);
            Assert.IsTrue(bob2.Italic == db.CompareImagesExpanded[0].Italic);
            Assert.IsTrue(bob2.ExpandCount == db.CompareImagesExpanded[0].ExpandCount);
            Assert.IsTrue(bob2.Text == db.CompareImagesExpanded[0].Text);
            Assert.IsTrue(bob2.X == db.CompareImagesExpanded[0].X);
            Assert.IsTrue(bob2.Y == db.CompareImagesExpanded[0].Y);

            try
            {
                File.Delete(tempFileName);
            }
            catch
            {
            }
        }
        public VobSubCharactersImport(BinaryOcrDb binaryOcrDb)
        {
            InitializeComponent();

            _existingDb = binaryOcrDb;

            labelInfo.Text = string.Empty;
            labelCurrentImage.Text = string.Empty;
            Text = string.Format("Import OCR images into \"{0}\"", Path.GetFileName(_existingDb.FileName));
            buttonCancel.Text = Configuration.Settings.Language.General.Cancel;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="VobSubEditCharacters"/> class.
        /// </summary>
        /// <param name="databaseFolderName">
        /// The database folder name.
        /// </param>
        /// <param name="additions">
        /// The additions.
        /// </param>
        /// <param name="binOcrDb">
        /// The bin ocr db.
        /// </param>
        internal VobSubEditCharacters(string databaseFolderName, List<VobSubOcr.ImageCompareAddition> additions, BinaryOcrDb binOcrDb)
        {
            this.InitializeComponent();
            this.labelExpandCount.Text = string.Empty;
            this._binOcrDb = binOcrDb;
            this.labelCount.Text = string.Empty;
            if (additions != null)
            {
                this.Additions = new List<VobSubOcr.ImageCompareAddition>();
                foreach (var a in additions)
                {
                    this.Additions.Add(a);
                }

                const int makeHigher = 40;
                this.labelImageCompareFiles.Top = this.labelImageCompareFiles.Top - makeHigher;
                this.listBoxFileNames.Top = this.listBoxFileNames.Top - makeHigher;
                this.listBoxFileNames.Height = this.listBoxFileNames.Height + makeHigher;
                this.groupBoxCurrentCompareImage.Top = this.groupBoxCurrentCompareImage.Top - makeHigher;
                this.groupBoxCurrentCompareImage.Height = this.groupBoxCurrentCompareImage.Height + makeHigher;
            }

            this.labelImageInfo.Text = string.Empty;
            this.pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;

            this._directoryPath = Configuration.VobSubCompareFolder + databaseFolderName + Path.DirectorySeparatorChar;
            if (!File.Exists(this._directoryPath + "Images.xml"))
            {
                this._compareDoc.LoadXml("<OcrBitmaps></OcrBitmaps>");
            }
            else
            {
                this._compareDoc.Load(this._directoryPath + "Images.xml");
            }

            this.Refill(this.Additions);

            this.Text = Configuration.Settings.Language.VobSubEditCharacters.Title;
            this.labelChooseCharacters.Text = Configuration.Settings.Language.VobSubEditCharacters.ChooseCharacter;
            this.labelImageCompareFiles.Text = Configuration.Settings.Language.VobSubEditCharacters.ImageCompareFiles;
            this.groupBoxCurrentCompareImage.Text = Configuration.Settings.Language.VobSubEditCharacters.CurrentCompareImage;
            this.labelTextAssociatedWithImage.Text = Configuration.Settings.Language.VobSubEditCharacters.TextAssociatedWithImage;
            this.checkBoxItalic.Text = Configuration.Settings.Language.VobSubEditCharacters.IsItalic;
            this.buttonUpdate.Text = Configuration.Settings.Language.VobSubEditCharacters.Update;
            this.buttonDelete.Text = Configuration.Settings.Language.VobSubEditCharacters.Delete;
            this.labelDoubleSize.Text = Configuration.Settings.Language.VobSubEditCharacters.ImageDoubleSize;
            this.buttonOK.Text = Configuration.Settings.Language.General.Ok;
            this.buttonCancel.Text = Configuration.Settings.Language.General.Cancel;
            Utilities.FixLargeFonts(this, this.buttonOK);
        }
        public void TestMethodBinOcrSaveLoadTestExceptions()
        {
            string tempFileName = Path.GetTempFileName();
            var db = new BinaryOcrDb(tempFileName);
            var nbmp = new NikseBitmap(2, 2);
            nbmp.SetPixel(0, 0, Color.Transparent);
            nbmp.SetPixel(1, 0, Color.Transparent);
            nbmp.SetPixel(1, 0, Color.Transparent);
            nbmp.SetPixel(1, 1, Color.White);

            var bob = new BinaryOcrBitmap(nbmp);
            bob.Text = "S";
            db.Add(bob);

            nbmp.SetPixel(0, 0, Color.White);
            var bob2 = new BinaryOcrBitmap(nbmp);
            bob2.X = 2;
            bob2.Y = 4;
            bob2.Text = null;
            bob2.Italic = true;
            bob2.ExpandCount = 3;
            bob2.ExpandedList = new System.Collections.Generic.List<BinaryOcrBitmap>();
            bob2.ExpandedList.Add(bob2);
            try
            {
                db.Add(bob2);
            }
            catch
            {
                return;
            }
            Assert.Fail();

            try
            {
                File.Delete(tempFileName);
            }
            catch
            {
            }
        }
        internal void Initialize(string databaseFolderName, List<VobSubOcr.CompareMatch> matches, List<Bitmap> imageSources, BinaryOcrDb binOcrDb)
        {
            _binOcrDb = binOcrDb;
            _matches = matches;
            _imageSources = imageSources;

            if (_binOcrDb == null)
            {
                ImageCompareDocument = new XmlDocument();
                _directoryPath = Configuration.VobSubCompareFolder + databaseFolderName + Path.DirectorySeparatorChar;
                if (!File.Exists(_directoryPath + "Images.xml"))
                    ImageCompareDocument.LoadXml("<OcrBitmaps></OcrBitmaps>");
                else
                    ImageCompareDocument.Load(_directoryPath + "Images.xml");
            }

            for (int i = 0; i < _matches.Count; i++)
                listBoxInspectItems.Items.Add(_matches[i]);
            if (listBoxInspectItems.Items.Count > 0)
                listBoxInspectItems.SelectedIndex = 0;
            ShowCount();
        }
Example #6
0
        private void LoadImageCompareBitmaps()
        {
            DisposeImageCompareBitmaps();
            _binaryOcrDb = null;

            if (_ocrMethodIndex == _ocrMethodImageCompare)
            {
                LoadOldCompareImages();
            }
            else if (_ocrMethodIndex == _ocrMethodBinaryImageCompare)
            {
                string db = Configuration.OcrFolder + comboBoxCharacterDatabase.SelectedItem + ".db";
                _binaryOcrDb = new BinaryOcrDb(db, true);
            }
        }
Example #7
0
        private void ComboBoxOcrMethodSelectedIndexChanged(object sender, EventArgs e)
        {
            _icThreadsStop = true;
            _binaryOcrDb = null;
            _nOcrDb = null;
            _ocrMethodIndex = comboBoxOcrMethod.SelectedIndex;
            if (_ocrMethodIndex == _ocrMethodTesseract)
            {
                ShowOcrMethodGroupBox(GroupBoxTesseractMethod);
                Configuration.Settings.VobSubOcr.LastOcrMethod = "Tesseract";
            }
            else if (_ocrMethodIndex == _ocrMethodImageCompare)
            {
                ShowOcrMethodGroupBox(groupBoxImageCompareMethod);
                Configuration.Settings.VobSubOcr.LastOcrMethod = "BitmapCompare";
                checkBoxPromptForUnknownWords.Checked = false;
                LoadImageCompareCharacterDatabaseList();
            }
            else if (_ocrMethodIndex == _ocrMethodNocr)
            {
                ShowOcrMethodGroupBox(groupBoxNOCR);
                Configuration.Settings.VobSubOcr.LastOcrMethod = "nOCR";
                SetSpellCheckLanguage(Configuration.Settings.VobSubOcr.LineOcrLastSpellCheck);

                comboBoxNOcrLanguage.Items.Clear();
                int index = 0;
                int selIndex = 0;
                foreach (string fileName in Directory.GetFiles(Configuration.OcrFolder, "*.nocr"))
                {
                    string s = Path.GetFileNameWithoutExtension(fileName);
                    if (s == Configuration.Settings.VobSubOcr.LineOcrLastLanguages)
                        selIndex = index;
                    comboBoxNOcrLanguage.Items.Add(s);
                    index++;
                }
                if (comboBoxNOcrLanguage.Items.Count > 0)
                    comboBoxNOcrLanguage.SelectedIndex = selIndex;
            }
            else if (_ocrMethodIndex == _ocrMethodBinaryImageCompare)
            {
                ShowOcrMethodGroupBox(groupBoxImageCompareMethod);
                Configuration.Settings.VobSubOcr.LastOcrMethod = "BinaryImageCompare";
                checkBoxPromptForUnknownWords.Checked = false;
                numericUpDownMaxErrorPct.Minimum = 0;
                _binaryOcrDb = new BinaryOcrDb(_binaryOcrDbFileName, true);
                LoadImageCompareCharacterDatabaseList();
            }
            else if (_ocrMethodIndex == _ocrMethodModi)
            {
                ShowOcrMethodGroupBox(groupBoxModiMethod);
                Configuration.Settings.VobSubOcr.LastOcrMethod = "MODI";
            }
            SubtitleListView1SelectedIndexChanged(null, null);
        }
Example #8
0
        private void ButtonStartOcrClick(object sender, EventArgs e)
        {
            Configuration.Settings.VobSubOcr.RightToLeft = checkBoxRightToLeft.Checked;
            _lastLine = null;
            buttonOK.Enabled = false;
            buttonCancel.Enabled = false;
            buttonStartOcr.Enabled = false;
            buttonStop.Enabled = true;
            buttonNewCharacterDatabase.Enabled = false;
            buttonEditCharacterDatabase.Enabled = false;
            _fromMenuItem = false;
            _abort = false;
            _autoBreakLines = checkBoxAutoBreakLines.Checked;
            listBoxUnknownWords.Items.Clear();
            int max = GetSubtitleCount();

            if (_ocrMethodIndex == _ocrMethodTesseract && _tesseractAsyncStrings == null)
            {
                _nOcrDb = null;
                _tesseractAsyncStrings = new string[max];
                _tesseractAsyncIndex = (int)numericUpDownStartNumber.Value + 5;
                _tesseractThread = new BackgroundWorker();
                _tesseractThread.DoWork += TesseractThreadDoWork;
                _tesseractThread.RunWorkerCompleted += TesseractThreadRunWorkerCompleted;
                _tesseractThread.WorkerSupportsCancellation = true;
                if (_tesseractAsyncIndex >= 0 && _tesseractAsyncIndex < max)
                    _tesseractThread.RunWorkerAsync(GetSubtitleBitmap(_tesseractAsyncIndex));
            }
            else if (_ocrMethodIndex == _ocrMethodImageCompare)
            {
                if (_compareBitmaps == null)
                    LoadImageCompareBitmaps();
                _numericUpDownMaxErrorPct = (double)numericUpDownMaxErrorPct.Value;
            }
            else if (_ocrMethodIndex == _ocrMethodNocr)
            {
                if (_nOcrDb == null)
                    LoadNOcrWithCurrentLanguage();

                if (_nOcrDb == null)
                {
                    MessageBox.Show("Fatal - No NOCR dictionary loaded!");
                    SetButtonsEnabledAfterOcrDone();
                    return;
                }

                _nocrThreadsStop = false;
                _nocrThreadResults = new string[_subtitle.Paragraphs.Count];
                int noOfThreads = Environment.ProcessorCount - 1;
                if (noOfThreads >= max)
                    noOfThreads = max - 1;
                int start = (int)numericUpDownStartNumber.Value + 5;
                if (noOfThreads >= 1 && max > 5)
                {
                    // finder letter size (uppercase/lowercase)
                    int testIndex = 0;
                    while (testIndex < 6 && (_nocrLastLowercaseHeight == -1 || _nocrLastUppercaseHeight == -1))
                    {
                        NOCRIntialize(GetSubtitleBitmap(testIndex));
                        testIndex++;
                    }

                    for (int i = 0; i < noOfThreads; i++)
                    {
                        if (start + i < max)
                        {
                            var bw = new BackgroundWorker();
                            var p = new NOcrThreadParameter(GetSubtitleBitmap(start + i), start + i, _nOcrDb.OcrCharacters, bw, noOfThreads, _unItalicFactor, checkBoxNOcrItalic.Checked, (int)numericUpDownNumberOfPixelsIsSpaceNOCR.Value, checkBoxRightToLeft.Checked);
                            p.NOcrLastLowercaseHeight = _nocrLastLowercaseHeight;
                            p.NOcrLastUppercaseHeight = _nocrLastUppercaseHeight;
                            bw.DoWork += NOcrThreadDoWork;
                            bw.RunWorkerCompleted += NOcrThreadRunWorkerCompleted;
                            bw.RunWorkerAsync(p);
                        }
                    }
                }
            }
            else if (_ocrMethodIndex == _ocrMethodBinaryImageCompare)
            {
                if (_binaryOcrDb == null)
                {
                    _binaryOcrDbFileName = Configuration.OcrFolder + "Latin.db";
                    _binaryOcrDb = new BinaryOcrDb(_binaryOcrDbFileName, true);
                }
                _nOcrDb = new NOcrDb(_binaryOcrDb.FileName.Replace(".db", ".nocr"));
                checkBoxNOcrCorrect.Checked = true;
                _numericUpDownMaxErrorPct = (double)numericUpDownMaxErrorPct.Value;
            }

            progressBar1.Maximum = max;
            progressBar1.Value = 0;
            progressBar1.Visible = true;

            _mainOcrTimerMax = max;
            _mainOcrIndex = (int)numericUpDownStartNumber.Value - 1;
            _mainOcrTimer = new Timer();
            _mainOcrTimer.Tick += mainOcrTimer_Tick;
            _mainOcrTimer.Interval = 5;
            _mainOcrRunning = true;
            subtitleListView1.MultiSelect = false;
            mainOcrTimer_Tick(null, null);

            if (_ocrMethodIndex == _ocrMethodImageCompare)
            {
                _icThreadsStop = false;
                _icThreadResults = new string[_subtitle.Paragraphs.Count];
                int noOfThreads = Environment.ProcessorCount - 2; // -1 or -2?
                if (noOfThreads >= max)
                    noOfThreads = max - 1;
                int start = (int)numericUpDownStartNumber.Value + 5;
                if (noOfThreads > 2)
                    noOfThreads = 2; // Threading is not really good - subtitle picture creation should probably be threaded also/instead
                for (int i = 0; i < noOfThreads; i++)
                {
                    if (start + i < max)
                    {
                        Application.DoEvents();
                        var bw = new BackgroundWorker();
                        var p = new ImageCompareThreadParameter(GetSubtitleBitmap(start + i), start + i, _compareBitmaps, bw, noOfThreads, (int)numericUpDownPixelsIsSpace.Value, checkBoxRightToLeft.Checked, (float)numericUpDownMaxErrorPct.Value);
                        bw.DoWork += ImageCompareThreadDoWork;
                        bw.RunWorkerCompleted += ImageCompareThreadRunWorkerCompleted;
                        bw.RunWorkerAsync(p);
                    }
                }
            }
        }
Example #9
0
 private void ButtonNewCharacterDatabaseClick(object sender, EventArgs e)
 {
     using (var newFolder = new VobSubOcrNewFolder(_ocrMethodIndex == _ocrMethodImageCompare))
     {
         if (newFolder.ShowDialog(this) == DialogResult.OK)
         {
             if (_ocrMethodIndex == _ocrMethodBinaryImageCompare)
             {
                 try
                 {
                     string fileName = Path.Combine(Configuration.OcrFolder, newFolder.FolderName + ".db");
                     if (File.Exists(fileName))
                     {
                         MessageBox.Show("OCR db already exists!");
                         return;
                     }
                     comboBoxCharacterDatabase.Items.Add(newFolder.FolderName);
                     comboBoxCharacterDatabase.SelectedIndex = comboBoxCharacterDatabase.Items.Count - 1;
                     _binaryOcrDb = new BinaryOcrDb(fileName);
                     _binaryOcrDb.Save();
                 }
                 catch (Exception exception)
                 {
                     MessageBox.Show(exception.Message);
                 }
             }
             else
             {
                 _vobSubOcrSettings.LastImageCompareFolder = newFolder.FolderName;
                 LoadImageCompareCharacterDatabaseList();
                 LoadImageCompareBitmaps();
             }
         }
     }
 }
Example #10
0
        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)
            {
                index = bobExactMatch;
                smallestDifference = 0;
                smallestIndex = bobExactMatch;
                return;
            }

            if (maxDiff < 0.2 || target.Width < 3 || target.Height < 5)
                return;

            int numberOfForegroundColors = bob.NumberOfColoredPixels;
            const int minForeColorMatch = 90;

            index = 0;
            foreach (var compareItem in binOcrDb.CompareImages)
            {
                if (compareItem.Width == target.Width && compareItem.Height == target.Height) // precise math in size
                {
                    if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < 3)
                    {
                        int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem, target);
                        if (dif < smallestDifference)
                        {
                            smallestDifference = dif;
                            smallestIndex = index;
                            if (dif < 3)
                            {
                                break; // foreach ending
                            }
                        }
                    }
                }
                index++;
            }

            if (smallestDifference > 1)
            {
                index = 0;
                foreach (var compareItem in binOcrDb.CompareImages)
                {
                    if (compareItem.Width == target.Width && compareItem.Height == target.Height) // precise math in size
                    {
                        if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < 40)
                        {
                            int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem, target);
                            if (dif < smallestDifference)
                            {
                                smallestDifference = dif;
                                smallestIndex = index;
                                if (dif == 0)
                                {
                                    break; // foreach ending
                                }
                            }
                        }
                    }
                    index++;
                }
            }

            if (target.Width > 16 && target.Height > 16 && smallestDifference > 2) // for other than very narrow letter (like 'i' and 'l' and 'I'), try more sizes
            {
                index = 0;
                foreach (var compareItem in binOcrDb.CompareImages)
                {
                    if (compareItem.Width == target.Width && compareItem.Height == target.Height - 1)
                    {
                        if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < minForeColorMatch)
                        {
                            int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem, target);
                            if (dif < smallestDifference)
                            {
                                smallestDifference = dif;
                                smallestIndex = index;
                                if (dif == 0)
                                    break; // foreach ending
                            }
                        }
                    }
                    index++;
                }

                if (smallestDifference > 2)
                {
                    index = 0;
                    foreach (var compareItem in binOcrDb.CompareImages)
                    {
                        if (compareItem.Width == target.Width && compareItem.Height == target.Height + 1)
                        {
                            if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < minForeColorMatch)
                            {
                                int dif = NikseBitmapImageSplitter.IsBitmapsAlike(target, compareItem);
                                if (dif < smallestDifference)
                                {
                                    smallestDifference = dif;
                                    smallestIndex = index;
                                    if (dif == 0)
                                        break; // foreach ending
                                }
                            }
                        }
                        index++;
                    }
                }

                if (smallestDifference > 3)
                {
                    index = 0;
                    foreach (var compareItem in binOcrDb.CompareImages)
                    {
                        if (compareItem.Width == target.Width + 1 && compareItem.Height == target.Height + 1)
                        {
                            if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < minForeColorMatch)
                            {
                                int dif = NikseBitmapImageSplitter.IsBitmapsAlike(target, compareItem);
                                if (dif < smallestDifference)
                                {
                                    smallestDifference = dif;
                                    smallestIndex = index;
                                    if (dif == 0)
                                        break; // foreach ending
                                }
                            }
                        }
                        index++;
                    }
                }

                if (smallestDifference > 5)
                {
                    index = 0;
                    foreach (var compareItem in binOcrDb.CompareImages)
                    {
                        if (compareItem.Width == target.Width - 1 && compareItem.Height == target.Height - 1)
                        {
                            if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < minForeColorMatch)
                            {
                                int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem, target);
                                if (dif < smallestDifference)
                                {
                                    smallestDifference = dif;
                                    smallestIndex = index;
                                    if (dif == 0)
                                        break; // foreach ending
                                }
                            }
                        }
                        index++;
                    }
                }

                if (smallestDifference > 5)
                {
                    index = 0;
                    foreach (var compareItem in binOcrDb.CompareImages)
                    {
                        if (compareItem.Width - 1 == target.Width && compareItem.Height == target.Height)
                        {
                            if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < minForeColorMatch)
                            {
                                int dif = NikseBitmapImageSplitter.IsBitmapsAlike(target, compareItem);
                                if (dif < smallestDifference)
                                {
                                    smallestDifference = dif;
                                    smallestIndex = index;
                                    if (dif == 0)
                                        break; // foreach ending
                                }
                            }
                        }
                        index++;
                    }
                }

                if (smallestDifference > 9 && target.Width > 11)
                {
                    index = 0;
                    foreach (var compareItem in binOcrDb.CompareImages)
                    {
                        if (compareItem.Width == target.Width - 2 && compareItem.Height == target.Height)
                        {
                            if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < minForeColorMatch)
                            {
                                int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem, target);
                                if (dif < smallestDifference)
                                {
                                    smallestDifference = dif;
                                    smallestIndex = index;
                                    if (dif == 0)
                                        break; // foreach ending
                                }
                            }
                        }
                        index++;
                    }
                }

                if (smallestDifference > 9 && target.Width > 14)
                {
                    index = 0;
                    foreach (var compareItem in binOcrDb.CompareImages)
                    {
                        if (compareItem.Width == target.Width - 3 && compareItem.Height == target.Height)
                        {
                            if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < minForeColorMatch)
                            {
                                int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem, target);
                                if (dif < smallestDifference)
                                {
                                    smallestDifference = dif;
                                    smallestIndex = index;
                                    if (dif == 0)
                                        break; // foreach ending
                                }
                            }
                        }
                        index++;
                    }
                }

                if (smallestDifference > 9 && target.Width > 14)
                {
                    index = 0;
                    foreach (var compareItem in binOcrDb.CompareImages)
                    {
                        if (compareItem.Width == target.Width && compareItem.Height == target.Height - 3)
                        {
                            if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < minForeColorMatch)
                            {
                                int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem, target);
                                if (dif < smallestDifference)
                                {
                                    smallestDifference = dif;
                                    smallestIndex = index;
                                    if (dif == 0)
                                        break; // foreach ending
                                }
                            }
                        }
                        index++;
                    }
                }

                if (smallestDifference > 9 && target.Width > 14)
                {
                    index = 0;
                    foreach (var compareItem in binOcrDb.CompareImages)
                    {
                        if (compareItem.Width - 2 == target.Width && compareItem.Height == target.Height)
                        {
                            if (Math.Abs(compareItem.NumberOfColoredPixels - numberOfForegroundColors) < minForeColorMatch)
                            {
                                int dif = NikseBitmapImageSplitter.IsBitmapsAlike(target, compareItem);
                                if (dif < smallestDifference)
                                {
                                    smallestDifference = dif;
                                    smallestIndex = index;
                                    if (dif == 0)
                                        break; // foreach ending
                                }
                            }
                        }
                        index++;
                    }
                }
            }

            if (smallestDifference == 0)
            {
                if (smallestIndex > 200)
                {
                    var hit = binOcrDb.CompareImages[smallestIndex];
                    binOcrDb.CompareImages.RemoveAt(smallestIndex);
                    binOcrDb.CompareImages.Insert(0, hit);
                    smallestIndex = 0;
                    index = 0;
                }
            }
        }
 private void LoadImagesInListView()
 {
     int existingMatches = 0;
     listView1.SmallImageList = imageList1;
     listView1.BeginUpdate();
     var importDb = new BinaryOcrDb(openFileDialog1.FileName, true);
     var list = new List<BinaryOcrBitmap>();
     list.AddRange(importDb.CompareImages);
     list.AddRange(importDb.CompareImagesExpanded);
     foreach (var bob in list.OrderBy(p => p.Text))
     {
         if (bob.ExpandCount > 0 && _existingDb.FindExactMatchExpanded(bob) < 0)
         {
             AddToListView(bob);
         }
         else if (bob.ExpandCount == 0 && _existingDb.FindExactMatch(bob) < 0)
         {
             AddToListView(bob);
         }
         else
         {
             existingMatches++;
         }
     }
     listView1.EndUpdate();
     if (listView1.Items.Count > 0)
     {
         listView1.Items[0].Selected = true;
         listView1.Items[0].Focused = true;
     }
     labelInfo.Text = string.Format("Images found not in current db: {0:#,##0} ({1:#,##0} matches already in current db)", imageList1.Images.Count, existingMatches);
 }
        /// <summary>
        /// The button start ocr click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ButtonStartOcrClick(object sender, EventArgs e)
        {
            Configuration.Settings.VobSubOcr.RightToLeft = this.checkBoxRightToLeft.Checked;
            this._lastLine = null;
            this.buttonOK.Enabled = false;
            this.buttonCancel.Enabled = false;
            this.buttonStartOcr.Enabled = false;
            this.buttonStop.Enabled = true;
            this.buttonNewCharacterDatabase.Enabled = false;
            this.buttonEditCharacterDatabase.Enabled = false;

            this._abort = false;

            int max = this.GetSubtitleCount();

            if (this.comboBoxOcrMethod.SelectedIndex == 0 && this._tesseractAsyncStrings == null)
            {
                this._nOcrDb = null;
                this._tesseractAsyncStrings = new string[max];
                this._tesseractAsyncIndex = (int)this.numericUpDownStartNumber.Value + 5;
                this._tesseractThread = new BackgroundWorker();
                this._tesseractThread.DoWork += this.TesseractThreadDoWork;
                this._tesseractThread.RunWorkerCompleted += this.TesseractThreadRunWorkerCompleted;
                this._tesseractThread.WorkerSupportsCancellation = true;
                if (this._tesseractAsyncIndex >= 0 && this._tesseractAsyncIndex < max)
                {
                    this._tesseractThread.RunWorkerAsync(this.GetSubtitleBitmap(this._tesseractAsyncIndex));
                }
            }
            else if (this.comboBoxOcrMethod.SelectedIndex == 1)
            {
                if (this._compareBitmaps == null)
                {
                    this.LoadImageCompareBitmaps();
                }
            }
            else if (this.comboBoxOcrMethod.SelectedIndex == 3)
            {
                if (this._nOcrDb == null)
                {
                    this.LoadNOcrWithCurrentLanguage();
                }

                if (this._nOcrDb == null)
                {
                    MessageBox.Show("Fatal - No NOCR dictionary loaded!");
                    this.SetButtonsEnabledAfterOcrDone();
                    return;
                }

                this._nocrThreadsStop = false;
                this._nocrThreadResults = new string[this._subtitle.Paragraphs.Count];
                int noOfThreads = Environment.ProcessorCount - 1;
                if (noOfThreads >= max)
                {
                    noOfThreads = max - 1;
                }

                int start = (int)this.numericUpDownStartNumber.Value + 5;
                if (noOfThreads >= 1 && max > 5)
                {
                    // finder letter size (uppercase/lowercase)
                    int testIndex = 0;
                    while (testIndex < 6 && (this._nocrLastLowercaseHeight == -1 || this._nocrLastUppercaseHeight == -1))
                    {
                        this.NOCRIntialize(this.GetSubtitleBitmap(testIndex));
                        testIndex++;
                    }

                    for (int i = 0; i < noOfThreads; i++)
                    {
                        if (start + i < max)
                        {
                            var bw = new BackgroundWorker();
                            var p = new NOcrThreadParameter(this.GetSubtitleBitmap(start + i), start + i, this._nOcrDb.OcrCharacters, bw, noOfThreads, this._unItalicFactor, this.checkBoxNOcrItalic.Checked, (int)this.numericUpDownNumberOfPixelsIsSpaceNOCR.Value, this.checkBoxRightToLeft.Checked);
                            p.NOcrLastLowercaseHeight = this._nocrLastLowercaseHeight;
                            p.NOcrLastUppercaseHeight = this._nocrLastUppercaseHeight;
                            bw.DoWork += NOcrThreadDoWork;
                            bw.RunWorkerCompleted += this.NOcrThreadRunWorkerCompleted;
                            bw.RunWorkerAsync(p);
                        }
                    }
                }
            }
            else if (this.comboBoxOcrMethod.SelectedIndex == 4)
            {
                if (this._binaryOcrDb == null)
                {
                    this._binaryOcrDbFileName = Configuration.OcrFolder + "Latin.db";
                    this._binaryOcrDb = new BinaryOcrDb(this._binaryOcrDbFileName, true);
                }

                this._nOcrDb = new NOcrDb(this._binaryOcrDb.FileName.Replace(".db", ".nocr"));
            }

            this.progressBar1.Maximum = max;
            this.progressBar1.Value = 0;
            this.progressBar1.Visible = true;

            this._mainOcrTimerMax = max;
            this._mainOcrIndex = (int)this.numericUpDownStartNumber.Value - 1;
            this._mainOcrTimer = new Timer();
            this._mainOcrTimer.Tick += this.mainOcrTimer_Tick;
            this._mainOcrTimer.Interval = 5;
            this._mainOcrRunning = true;
            this.subtitleListView1.MultiSelect = false;
            this.mainOcrTimer_Tick(null, null);

            if (this.comboBoxOcrMethod.SelectedIndex == 1)
            {
                this._icThreadsStop = false;
                this._icThreadResults = new string[this._subtitle.Paragraphs.Count];
                int noOfThreads = Environment.ProcessorCount - 2; // -1 or -2?
                if (noOfThreads >= max)
                {
                    noOfThreads = max - 1;
                }

                int start = (int)this.numericUpDownStartNumber.Value + 5;
                if (noOfThreads > 2)
                {
                    noOfThreads = 2; // Threading is not really good - subtitle picture creation should probably be threaded also/instead
                }

                for (int i = 0; i < noOfThreads; i++)
                {
                    if (start + i < max)
                    {
                        Application.DoEvents();
                        var bw = new BackgroundWorker();
                        var p = new ImageCompareThreadParameter(this.GetSubtitleBitmap(start + i), start + i, this._compareBitmaps, bw, noOfThreads, (int)this.numericUpDownPixelsIsSpace.Value, this.checkBoxRightToLeft.Checked, (float)this.numericUpDownMaxErrorPct.Value);
                        bw.DoWork += ImageCompareThreadDoWork;
                        bw.RunWorkerCompleted += this.ImageCompareThreadRunWorkerCompleted;
                        bw.RunWorkerAsync(p);
                    }
                }
            }
        }
        /// <summary>
        /// The load image compare bitmaps.
        /// </summary>
        private void LoadImageCompareBitmaps()
        {
            this.DisposeImageCompareBitmaps();
            this._binaryOcrDb = null;

            if (this.comboBoxOcrMethod.SelectedIndex == 1)
            {
                this.LoadOldCompareImages();
            }
            else if (this.comboBoxOcrMethod.SelectedIndex == 4)
            {
                string db = Configuration.OcrFolder + this.comboBoxCharacterDatabase.SelectedItem + ".db";
                this._binaryOcrDb = new BinaryOcrDb(db, true);
            }
        }