Beispiel #1
0
 public NikseBitmap(NikseBitmap input)
 {
     Width = input.Width;
     Height = input.Height;
     _bitmapData = new byte[input._bitmapData.Length];
     Buffer.BlockCopy(input._bitmapData, 0, _bitmapData, 0, _bitmapData.Length);
 }
 public ImageSplitterItem(int x, int y, NikseBitmap bitmap)
 {
     X = x;
     Y = y;
     NikseBitmap = bitmap;
     SpecialCharacter = null;
 }
        public static NikseBitmap CropTopAndBottom(NikseBitmap bmp, out int topCropping)
        {
            int startTop = 0;
            int maxTop = bmp.Height - 2;
            if (maxTop > bmp.Height)
            {
                maxTop = bmp.Height;
            }

            for (int y = 0; y < maxTop; y++)
            {
                bool allTransparent = true;
                for (int x = 1; x < bmp.Width - 1; x++)
                {
                    int a = bmp.GetAlpha(x, y);
                    if (a != 0)
                    {
                        allTransparent = false;
                        break;
                    }
                }

                if (!allTransparent)
                {
                    break;
                }

                startTop++;
            }

            //if (startTop > 9)
            //startTop -= 5; // if top space > 9, then allways leave blank 5 pixels on top (so . is not confused with ').
            topCropping = startTop;

            int height = bmp.Height;
            bool bottomCroppingDone = false;
            for (int y = bmp.Height - 1; y > 3; y--)
            {
                for (int x = 1; x < bmp.Width - 1; x++)
                {
                    int a = bmp.GetAlpha(x, y);
                    if (a != 0)
                    {
                        bottomCroppingDone = true;
                        break;
                    }
                }

                height = y;
                if (bottomCroppingDone)
                {
                    break;
                }
            }

            return bmp.CopyRectangle(new Rectangle(0, startTop, bmp.Width, height - startTop + 1));
        }
        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 static NikseBitmap CropTopAndBottom(NikseBitmap bmp, out int topCropping, int maxDifferentPixelsOnLine)
        {
            int startTop = 0;
            int maxTop = bmp.Height - 2;
            if (maxTop > bmp.Height)
                maxTop = bmp.Height;

            for (int y = 0; y < maxTop; y++)
            {
                int difference = 0;
                bool allTransparent = true;
                for (int x = 1; x < bmp.Width - 1; x++)
                {
                    int a = bmp.GetAlpha(x, y);
                    if (a != 0)
                    {
                        difference++;
                        if (difference >= maxDifferentPixelsOnLine)
                        {
                            allTransparent = false;
                            break;
                        }
                    }
                }
                if (!allTransparent)
                    break;
                startTop++;
            }
            if (startTop > 9)
                startTop -= 5; // if top space > 9, then allways leave blank 5 pixels on top (so . is not confused with ').
            topCropping = startTop;

            for (int y = bmp.Height - 1; y > 3; y--)
            {
                int difference = 0;
                bool allTransparent = true;
                for (int x = 1; x < bmp.Width - 1; x++)
                {
                    int a = bmp.GetAlpha(x, y);
                    if (a != 0)
                    {
                        difference++;
                        if (difference >= maxDifferentPixelsOnLine)
                        {
                            allTransparent = false;
                            break;
                        }
                    }
                }
                if (allTransparent == false)
                    return bmp.CopyRectangle(new Rectangle(0, startTop, bmp.Width - 1, y - startTop + 1));
            }
            return bmp;
        }
        internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showShrink)
        {
            listBoxLinesForeground.Items.Clear();
            listBoxlinesBackground.Items.Clear();
            NikseBitmap nbmp = new NikseBitmap(vobSubImage);
            nbmp.ReplaceTransparentWith(Color.Black);
            vobSubImage = nbmp.GetBitmap();

            radioButtonHot.Checked = true;
            ShrinkSelection = false;
            ExpandSelection = false;

            textBoxCharacters.Text = string.Empty;
            _nocrChar = new NOcrChar();
            _nocrChar.MarginTop = character.Y - character.ParentY;
            _imageWidth = character.NikseBitmap.Width;
            _imageHeight = character.NikseBitmap.Height;
            _drawLineOn = false;
            _warningNoNotForegroundLinesShown = false;

            buttonShrinkSelection.Visible = showShrink;

            if (position.X != -1 && position.Y != -1)
            {
                StartPosition = FormStartPosition.Manual;
                Left = position.X;
                Top = position.Y;
            }

            pictureBoxSubtitleImage.Image = vobSubImage;
            pictureBoxCharacter.Image = character.NikseBitmap.GetBitmap();

            Bitmap org = (Bitmap)vobSubImage.Clone();
            Bitmap bm = new Bitmap(org.Width, org.Height);
            Graphics g = Graphics.FromImage(bm);
            g.DrawImage(org, 0, 0, org.Width, org.Height);
            g.DrawRectangle(Pens.Red, character.X, character.Y, character.NikseBitmap.Width, character.NikseBitmap.Height - 1);
            g.Dispose();
            pictureBoxSubtitleImage.Image = bm;

            pictureBoxCharacter.Top = labelCharacters.Top + 16;
            SizePictureBox();
            checkBoxItalic.Checked = italicChecked;

            _history = new List<NOcrChar>();
            _historyIndex = -1;

            _nocrChar.Width = _imageWidth;
            _nocrChar.Height = _imageHeight;
            GenerateLineSegments(150, false, _nocrChar, new NikseBitmap(pictureBoxCharacter.Image as Bitmap));
            ShowOcrPoints();
            pictureBoxCharacter.Invalidate();
        }
 public ManagedBitmap(NikseBitmap nbmp)
 {
     Width = nbmp.Width;
     Height = nbmp.Height;
     _colors = new Color[Width * Height];
     for (int y = 0; y < Height; y++)
     {
         for (int x = 0; x < Width; x++)
         {
             this.SetPixel(x, y, nbmp.GetPixel(x, y));
         }
     }
 }
        internal void Initialize(Bitmap bitmap, int pixelsIsSpace, bool rightToLeft, NOcrDb nOcrDb, VobSubOcr vobSubOcr)
        {
            _bitmap = bitmap;
            var nbmp = new NikseBitmap(bitmap);
            nbmp.ReplaceNonWhiteWithTransparent();
            bitmap = nbmp.GetBitmap();
            _bitmap2 = bitmap;
            _nocrChars = nOcrDb.OcrCharacters;
            _matchList = new List<VobSubOcr.CompareMatch>();
            _vobSubOcr = vobSubOcr;

            int minLineHeight = 6;
            _imageList = NikseBitmapImageSplitter.SplitBitmapToLettersNew(nbmp, pixelsIsSpace, rightToLeft, Configuration.Settings.VobSubOcr.TopToBottom, minLineHeight);
            // _imageList = NikseBitmapImageSplitter.SplitBitmapToLetters(nbmp, pixelsIsSpace, rightToLeft, Configuration.Settings.VobSubOcr.TopToBottom);

            int index = 0;
            while (index < _imageList.Count)
            {
                ImageSplitterItem item = _imageList[index];
                if (item.NikseBitmap == null)
                {
                    listBoxInspectItems.Items.Add(item.SpecialCharacter);
                    _matchList.Add(null);
                }
                else
                {
                    nbmp = item.NikseBitmap;
                    nbmp.ReplaceNonWhiteWithTransparent();
                    item.Y += nbmp.CropTopTransparent(0);
                    nbmp.CropTransparentSidesAndBottom(0, true);
                    nbmp.ReplaceTransparentWith(Color.Black);

                    //get nocr matches
                    Nikse.SubtitleEdit.Forms.VobSubOcr.CompareMatch match = vobSubOcr.GetNOcrCompareMatchNew(item, nbmp, nOcrDb, false, false);
                    if (match == null)
                    {
                        listBoxInspectItems.Items.Add("?");
                        _matchList.Add(null);
                    }
                    else
                    {
                        listBoxInspectItems.Items.Add(match.Text);
                        _matchList.Add(match);
                    }
                }
                index++;
            }

        }
        internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showShrink, VobSubOcr.CompareMatch bestGuess, List<VobSubOcr.ImageCompareAddition> additions, VobSubOcr vobSubForm)
        {
            NikseBitmap nbmp = new NikseBitmap(vobSubImage);
            nbmp.ReplaceTransparentWith(Color.Black);
            vobSubImage = nbmp.GetBitmap();

            radioButtonHot.Checked = true;
            ShrinkSelection = false;
            ExpandSelection = false;

            textBoxCharacters.Text = string.Empty;
            _vobSubForm = vobSubForm;
            _additions = additions;
            _nocrChar = new NOcrChar();
            _nocrChar.MarginTop = character.Y - character.ParentY;
            _imageWidth = character.NikseBitmap.Width;
            _imageHeight = character.NikseBitmap.Height;
            _drawLineOn = false;
            _warningNoNotForegroundLinesShown = false;

            buttonShrinkSelection.Visible = showShrink;

            if (position.X != -1 && position.Y != -1)
            {
                StartPosition = FormStartPosition.Manual;
                Left = position.X;
                Top = position.Y;
            }

            pictureBoxSubtitleImage.Image = vobSubImage;
            pictureBoxCharacter.Image = character.NikseBitmap.GetBitmap();

            Bitmap org = (Bitmap)vobSubImage.Clone();
            Bitmap bm = new Bitmap(org.Width, org.Height);
            Graphics g = Graphics.FromImage(bm);
            g.DrawImage(org, 0, 0, org.Width, org.Height);
            g.DrawRectangle(Pens.Red, character.X, character.Y, character.NikseBitmap.Width, character.NikseBitmap.Height - 1);
            g.Dispose();
            pictureBoxSubtitleImage.Image = bm;

            pictureBoxCharacter.Top = labelCharacters.Top + 16;
            SizePictureBox();
            checkBoxItalic.Checked = italicChecked;

            _history = new List<NOcrChar>();
            _historyIndex = -1;
        }
        private void listBoxSubtitles_SelectedIndexChanged(object sender, EventArgs e)
        {
            int idx = listBoxSubtitles.SelectedIndex;
            if (idx < 0)
                return;

            int pid = _tsParser.SubtitlePacketIds[listBoxTracks.SelectedIndex];
            var list = _tsParser.GetDvbSubtitles(pid);

            var dvbBmp = list[idx].GetActiveImage();
            var nDvbBmp = new NikseBitmap(dvbBmp);
            nDvbBmp.CropTopTransparent(2);
            nDvbBmp.CropTransparentSidesAndBottom(2, true);
            dvbBmp.Dispose();
            var oldImage = pictureBox1.Image;
            pictureBox1.Image = nDvbBmp.GetBitmap();
            if (oldImage != null)
                oldImage.Dispose();
        }
Beispiel #11
0
        internal static ImageSplitterItem GetExpandedSelectionNew(NikseBitmap bitmap, List<ImageSplitterItem> expandSelectionList)
        {
            int minimumX = expandSelectionList[0].X;
            int maximumX = expandSelectionList[expandSelectionList.Count - 1].X + expandSelectionList[expandSelectionList.Count - 1].NikseBitmap.Width;
            int minimumY = expandSelectionList[0].Y;
            int maximumY = expandSelectionList[0].Y + expandSelectionList[0].NikseBitmap.Height;
            var nbmp = new NikseBitmap(bitmap.Width, bitmap.Height);
            foreach (ImageSplitterItem item in expandSelectionList)
            {
                for (int y = 0; y < item.NikseBitmap.Height; y++)
                {
                    for (int x = 0; x < item.NikseBitmap.Width; x++)
                    {
                        int a = item.NikseBitmap.GetAlpha(x, y);
                        if (a > 100)
                            nbmp.SetPixel(item.X + x, item.Y + y, Color.White);
                    }
                }
                if (item.Y < minimumY)
                    minimumY = item.Y;
                if (item.Y + item.NikseBitmap.Height > maximumY)
                    maximumY = item.Y + item.NikseBitmap.Height;
            }
            nbmp.CropTransparentSidesAndBottom(0, true);
            int topCropping;
            nbmp = NikseBitmapImageSplitter.CropTopAndBottom(nbmp, out topCropping);

            return new ImageSplitterItem(minimumX, minimumY, nbmp);
        }
Beispiel #12
0
 internal static ImageSplitterItem GetExpandedSelection(NikseBitmap bitmap, List<ImageSplitterItem> expandSelectionList, bool rightToLeft)
 {
     if (rightToLeft)
     {
         int minimumX = expandSelectionList[expandSelectionList.Count - 1].X - expandSelectionList[expandSelectionList.Count - 1].NikseBitmap.Width;
         int maximumX = expandSelectionList[0].X;
         int minimumY = expandSelectionList[0].Y;
         int maximumY = expandSelectionList[0].Y + expandSelectionList[0].NikseBitmap.Height;
         foreach (ImageSplitterItem item in expandSelectionList)
         {
             if (item.Y < minimumY)
                 minimumY = item.Y;
             if (item.Y + item.NikseBitmap.Height > maximumY)
                 maximumY = item.Y + item.NikseBitmap.Height;
         }
         var part = bitmap.CopyRectangle(new Rectangle(minimumX, minimumY, maximumX - minimumX, maximumY - minimumY));
         return new ImageSplitterItem(minimumX, minimumY, part);
     }
     else
     {
         int minimumX = expandSelectionList[0].X;
         int maximumX = expandSelectionList[expandSelectionList.Count - 1].X + expandSelectionList[expandSelectionList.Count - 1].NikseBitmap.Width;
         int minimumY = expandSelectionList[0].Y;
         int maximumY = expandSelectionList[0].Y + expandSelectionList[0].NikseBitmap.Height;
         foreach (ImageSplitterItem item in expandSelectionList)
         {
             if (item.Y < minimumY)
                 minimumY = item.Y;
             if (item.Y + item.NikseBitmap.Height > maximumY)
                 maximumY = item.Y + item.NikseBitmap.Height;
         }
         var part = bitmap.CopyRectangle(new Rectangle(minimumX, minimumY, maximumX - minimumX, maximumY - minimumY));
         return new ImageSplitterItem(minimumX, minimumY, part);
     }
 }
 private static bool IsVerticalLineTransparent(NikseBitmap bmp, ref int y, int x)
 {
     for (y = 0; y < bmp.Height - 1; y++)
     {
         var argb = bmp.GetPixelColors(x, y);
         if (argb[0] < 10 || IsColorClose(argb[0], argb[1], argb[2], argb[3], Color.Black, 280)) // still dark color...
         {
         }
         else
         {
             return false;
         }
     }
     return true;
 }
 private static void RemoveBlackBarRight(NikseBitmap bmp)
 {
     int xRemoveBlackBar = bmp.Width - 1;
     for (int yRemoveBlackBar = 0; yRemoveBlackBar < bmp.Height; yRemoveBlackBar++)
     {
         byte[] c = bmp.GetPixelColors(xRemoveBlackBar, yRemoveBlackBar);
         if (c[0] == 0 || IsColorClose(c[0], c[1], c[2], c[3], Color.Black, 280))
         {
             if (bmp.GetAlpha(xRemoveBlackBar - 1, yRemoveBlackBar) == 0)
                 bmp.SetPixel(xRemoveBlackBar, yRemoveBlackBar, Color.Transparent);
         }
     }
 }
        public static List<ImageSplitterItem> SplitVerticalTransparentOrBlack(NikseBitmap bmp)
        {
            int startY = 0;
            int size = 0;
            var parts = new List<ImageSplitterItem>();
            for (int y = 0; y < bmp.Height; y++)
            {
                bool allTransparent = true;
                for (int x = 0; x < bmp.Width; x++)
                {
                    Color c = bmp.GetPixel(x, y);
                    if (c.A > 20 && c.R + c.G + c.B > 20)
                    {
                        allTransparent = false;
                        break;
                    }
                }
                if (allTransparent)
                {
                    if (size > 2 && size <= 15)
                    {
                        size++; // at least 15 pixels, like top of 'i' or top of 'È'
                    }
                    else
                    {
                        if (size > 8)
                        {
                            NikseBitmap part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, size + 1));
                            //                            part.Save("c:\\line_0_to_width.bmp");
                            parts.Add(new ImageSplitterItem(0, startY, part));
                            //                            bmp.Save("c:\\original.bmp");
                        }
                        size = 0;
                        startY = y;
                    }
                }
                else
                {
                    size++;
                }

            }
            if (size > 2)
            {
                if (size == bmp.Height)
                    parts.Add(new ImageSplitterItem(0, startY, bmp));
                else
                    parts.Add(new ImageSplitterItem(0, startY, bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, size + 1))));
            }
            return parts;
        }
        private Bitmap GenerateImageFromTextWithStyle(string text, bool bold)
        {
            bool subtitleFontBold = bold;
            bool subtitleAlignLeft = true;
            bool subtitleAlignRight = false;

            text = Utilities.RemoveHtmlTags(text);

            Font font;
            try
            {
                var fontStyle = FontStyle.Regular;
                if (subtitleFontBold)
                    fontStyle = FontStyle.Bold;
                font = new Font(_subtitleFontName, _subtitleFontSize, fontStyle);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
                font = new Font(FontFamily.Families[0].Name, _subtitleFontSize);
            }
            var bmp = new Bitmap(400, 200);
            var g = Graphics.FromImage(bmp);

            SizeF textSize = g.MeasureString("Hj!", font);
            var lineHeight = (textSize.Height * 0.64f);

            textSize = g.MeasureString(Utilities.RemoveHtmlTags(text), font);
            g.Dispose();
            bmp.Dispose();
            int sizeX = (int)(textSize.Width * 0.8) + 40;
            int sizeY = (int)(textSize.Height * 0.8) + 30;
            if (sizeX < 1)
                sizeX = 1;
            if (sizeY < 1)
                sizeY = 1;
            bmp = new Bitmap(sizeX, sizeY);
            g = Graphics.FromImage(bmp);

            var lefts = new List<float>();
            foreach (string line in Utilities.RemoveHtmlFontTag(text.Replace("<i>", string.Empty).Replace("</i>", string.Empty)).Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
            {
                if (subtitleAlignLeft)
                    lefts.Add(5);
                else if (subtitleAlignRight)
                    lefts.Add(bmp.Width - (TextDraw.MeasureTextWidth(font, line, subtitleFontBold) + 15));
                else
                    lefts.Add((float)(bmp.Width - g.MeasureString(line, font).Width * 0.8 + 15) / 2);
            }

            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.CompositingQuality = CompositingQuality.HighQuality;

            var sf = new StringFormat();
            sf.Alignment = StringAlignment.Near;
            sf.LineAlignment = StringAlignment.Near;// draw the text to a path
            var path = new GraphicsPath();

            // display italic
            var sb = new StringBuilder();
            int i = 0;
            bool isItalic = false;
            float left = 5;
            if (lefts.Count > 0)
                left = lefts[0];
            float top = 5;
            bool newLine = false;
            int lineNumber = 0;
            float leftMargin = left;
            int newLinePathPoint = -1;
            Color c = _subtitleColor;
            var colorStack = new Stack<Color>();
            var lastText = new StringBuilder();
            while (i < text.Length)
            {
                if (text.Substring(i).StartsWith(Environment.NewLine))
                {
                    TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);

                    top += lineHeight;
                    newLine = true;
                    i += Environment.NewLine.Length - 1;
                    lineNumber++;
                    if (lineNumber < lefts.Count)
                    {
                        leftMargin = lefts[lineNumber];
                        left = leftMargin;
                    }
                }
                else
                {
                    sb.Append(text.Substring(i, 1));
                }
                i++;
            }
            if (sb.Length > 0)
                TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);

            if (_borderWidth > 0)
                g.DrawPath(new Pen(_borderColor, _borderWidth), path);
            g.FillPath(new SolidBrush(c), path);
            g.Dispose();
            var nbmp = new NikseBitmap(bmp);
            nbmp.CropTransparentSidesAndBottom(2, true);
            return nbmp.GetBitmap();
        }
        /// <summary>
        /// split into lines
        /// </summary>
        public static List<ImageSplitterItem> SplitToLines(NikseBitmap bmp, int minLineHeight, double averageLineHeight = -1)
        {
            int startY = 0;
            int size = 0;
            var parts = new List<ImageSplitterItem>();
            for (int y = 0; y < bmp.Height; y++)
            {
                if (bmp.IsLineTransparent(y))
                {

                    // check for appendix below text
                    bool appendix = y >= bmp.Height - minLineHeight;
                    if (!appendix && y < bmp.Height - 10 && size > minLineHeight && minLineHeight > 15)
                    {
                        bool yp1 = bmp.IsLineTransparent(y + 1);
                        bool yp2 = bmp.IsLineTransparent(y + 2);
                        bool yp3 = bmp.IsLineTransparent(y + 3);
                        bool yp4 = bmp.IsLineTransparent(y + 4);
                        bool yp5 = bmp.IsLineTransparent(y + 5);
                        if (!yp1 || !yp2 || !yp3 || !yp4 || !yp5)
                        {
                            bool yp6 = bmp.IsLineTransparent(y + 6);
                            bool yp7 = bmp.IsLineTransparent(y + 7);
                            bool yp8 = bmp.IsLineTransparent(y + 8);
                            bool yp9 = bmp.IsLineTransparent(y + 9);
                            if (yp6 && yp7 && yp8 && yp9)
                            {
                                appendix = true;
                            }
                        }
                    }

                    if (appendix || size > 1 && size <= minLineHeight)
                    {
                        size++; // at least 'lineMinHeight' pixels, like top of 'i'
                    }
                    else
                    {
                        if (size > 1)
                        {
                            var part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, size + 1));
                            parts.Add(new ImageSplitterItem(0, startY, part));
                        }
                        size = 0;
                        startY = y;
                    }
                }
                else
                {
                    size++;
                }
            }
            if (size > 1)
            {
                if (size == bmp.Height)
                {
                    if (size > 100)
                    {
                        return SplitToLinesTransparentOrBlack(bmp);
                    }

                    parts.Add(new ImageSplitterItem(0, startY, bmp));
                }
                else
                {
                    parts.Add(new ImageSplitterItem(0, startY, bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, size + 1))));
                }
            }
            if (parts.Count == 1 && averageLineHeight > 5 && bmp.Height > averageLineHeight * 3)
            {
                return SplitToLinesAggressive(bmp, minLineHeight, averageLineHeight);
            }
            return parts;
        }
        private static List<ImageSplitterItem> SplitToLinesAggressive(NikseBitmap bmp, int minLineHeight, double averageLineHeight)
        {
            int startY = 0;
            int size = 0;
            var parts = new List<ImageSplitterItem>();
            for (int y = 0; y < bmp.Height; y++)
            {
                int a;
                bool allTransparent = bmp.IsLineTransparent(y);

                if (size > 5 && size >= minLineHeight && size > averageLineHeight && !allTransparent && bmp.Width > 50 && y < bmp.Height - 5)
                {
                    var leftX = 0;
                    while (leftX < bmp.Width)
                    {
                        a = bmp.GetAlpha(leftX, y);
                        if (a != 0)
                        {
                            break;
                        }
                        leftX++;
                    }
                    var rightX = bmp.Width;
                    while (rightX > 0)
                    {
                        a = bmp.GetAlpha(rightX, y - 1);
                        if (a != 0)
                        {
                            break;
                        }
                        rightX--;
                    }
                    if (leftX >= rightX)
                    {
                        allTransparent = true;
                    }

                    leftX = 0;
                    while (leftX < bmp.Width)
                    {
                        a = bmp.GetAlpha(leftX, y - 1);
                        if (a != 0)
                        {
                            break;
                        }
                        leftX++;
                    }
                    rightX = bmp.Width;
                    while (rightX > 0)
                    {
                        a = bmp.GetAlpha(rightX, y);
                        if (a != 0)
                        {
                            break;
                        }
                        rightX--;
                    }
                    if (leftX >= rightX)
                    {
                        allTransparent = true;
                    }
                }

                if (allTransparent)
                {
                    if (size > 2 && size <= minLineHeight)
                    {
                        size++; // at least 'lineMinHeight' pixels, like top of 'i'
                    }
                    else
                    {
                        if (size > 2)
                        {
                            var part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, size + 1));
                            parts.Add(new ImageSplitterItem(0, startY, part));
                        }
                        size = 0;
                        startY = y;
                    }
                }
                else
                {
                    size++;
                }
            }
            if (size > 2)
            {
                if (size == bmp.Height)
                {
                    if (size > 100)
                    {
                        return SplitToLinesTransparentOrBlack(bmp);
                    }

                    parts.Add(new ImageSplitterItem(0, startY, bmp));
                }
                else
                {
                    parts.Add(new ImageSplitterItem(0, startY, bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, size + 1))));
                }
            }
            if (parts.Count == 1 && averageLineHeight > 5 && bmp.Height > averageLineHeight * 3)
            {
                return parts;
            }
            return parts;
        }
        public static List<ImageSplitterItem> SplitBitmapToLettersNew(NikseBitmap bmp, int xOrMorePixelsMakesSpace, bool rightToLeft, bool topToBottom, int minLineHeight, bool autoHeight, double averageLineHeight = -1)
        {
            var list = new List<ImageSplitterItem>();

            // split into separate lines
            var splitOld = SplitToLines(bmp, minLineHeight, averageLineHeight);

            List<ImageSplitterItem> lineBitmaps;
            if (autoHeight)
            {
                // fast horizontal split by x number of whole lines (3-4)
                var splitThreeBlankLines = SplitToLinesByMinTransparentHorizontalLines(bmp, minLineHeight, 3);
                var splitFourBlankLines = SplitToLinesByMinTransparentHorizontalLines(bmp, minLineHeight, 4);
                var splitBlankLines = splitThreeBlankLines.Count == splitFourBlankLines.Count ? splitFourBlankLines : splitThreeBlankLines;

                lineBitmaps = splitOld.Count > splitBlankLines.Count ? splitOld : splitBlankLines;

                if (lineBitmaps.Count == 1 && lineBitmaps[0].NikseBitmap?.Height > minLineHeight * 2.2)
                {
                    lineBitmaps = SplitToLinesNew(lineBitmaps[0], minLineHeight, averageLineHeight); // more advanced split (allows for up/down)
                }
            }
            else
            {
                lineBitmaps = splitOld;
            }

            //foreach (var bitmap in tempBitmaps)
            //{
            //    //                var height = bitmap.NikseBitmap.GetNonTransparentHeight();
            //    var bitmaps = SplitToLinesNew(bitmap, minLineHeight, averageLineHeight); // more advanced split (allows for up/down)
            //    lineBitmaps.AddRange(bitmaps);
            //}

            if (!topToBottom)
            {
                lineBitmaps.Reverse();
            }

            // split into letters
            for (int index = 0; index < lineBitmaps.Count; index++)
            {
                var b = lineBitmaps[index];
                if (index > 0)
                {
                    list.Add(new ImageSplitterItem(Environment.NewLine));
                }

                var line = new List<ImageSplitterItem>();
                foreach (var item in SplitHorizontalNew(b, xOrMorePixelsMakesSpace))
                {
                    item.Top = index > 0 ? item.Y - b.Y : item.Y;
                    item.ParentY = item.Y;
                    line.Add(item);
                }
                if (rightToLeft)
                {
                    line.Reverse();
                }

                list.AddRange(line);
            }
            return list;
        }
        /// <summary>
        /// split into lines
        /// </summary>
        public static List<ImageSplitterItem> SplitToLinesByMinTransparentHorizontalLines(NikseBitmap bmp, int minLineHeight, int minTransparentLines)
        {
            var parts = new List<ImageSplitterItem>();
            var startY = 0;
            var lastTransparentY = -1;
            var keysInSequence = 0;
            for (int y = minLineHeight; y < bmp.Height - minLineHeight; y++)
            {
                var isLineTransparent = bmp.IsLineTransparent(y);
                if (startY == y && isLineTransparent)
                {
                    startY++;
                    continue; // skip start
                }

                if (isLineTransparent)
                {
                    if (lastTransparentY == y - 1)
                    {
                        if (keysInSequence == 0)
                        {
                            keysInSequence++;
                        }

                        keysInSequence++;
                    }

                    if (keysInSequence > 2 && lastTransparentY - startY > minLineHeight)
                    {
                        var part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, lastTransparentY - startY - 1));
                        if (!part.IsImageOnlyTransparent() && part.GetNonTransparentHeight() >= minLineHeight)
                        {
                            var croppedTop = part.CropTopTransparent(0);
                            parts.Add(new ImageSplitterItem(0, startY + croppedTop, part));
                            startY = lastTransparentY + 1;
                        }
                    }
                    lastTransparentY = y;
                }
                else
                {
                    keysInSequence = 0;
                    lastTransparentY = -1;
                }
            }

            if (bmp.Height - startY > 1)
            {
                var part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, bmp.Height - startY));
                if (!part.IsImageOnlyTransparent())
                {
                    var croppedTop = part.CropTopTransparent(0);
                    parts.Add(new ImageSplitterItem(0, startY + croppedTop, part));
                }
            }

            return parts;
        }
Beispiel #21
0
        internal static CompareMatch GetNOcrCompareMatch(ImageSplitterItem targetItem, NikseBitmap parentBitmap, NOcrThreadParameter p)
        {
            bool italic;
            var expandedResult = NOcrFindExpandedMatch(parentBitmap, targetItem, targetItem.Y - targetItem.ParentY, p.NOcrChars);
            if (expandedResult != null)
                return new CompareMatch(expandedResult.Text, expandedResult.Italic, expandedResult.ExpandCount, null, expandedResult);

            var result = NOcrFindBestMatch(parentBitmap, targetItem, targetItem.Y - targetItem.ParentY, out italic, p.NOcrChars, p.UnItalicFactor, p.AdvancedItalicDetection, true);
            if (result == null)
                return null;

            // Fix uppercase/lowercase issues (not I/l)
            if (result.Text == "e")
                p.NOcrLastLowercaseHeight = targetItem.NikseBitmap.Height;
            else if (p.NOcrLastLowercaseHeight == -1 && result.Text == "a")
                p.NOcrLastLowercaseHeight = targetItem.NikseBitmap.Height;

            if (result.Text == "E" || result.Text == "H" || result.Text == "R" || result.Text == "D" || result.Text == "T")
                p.NOcrLastUppercaseHeight = targetItem.NikseBitmap.Height;
            else if (p.NOcrLastUppercaseHeight == -1 && result.Text == "M")
                p.NOcrLastUppercaseHeight = targetItem.NikseBitmap.Height;

            if (result.Text == "V" || result.Text == "W" || result.Text == "U" || result.Text == "S" || result.Text == "Z" || result.Text == "O" || result.Text == "X" || result.Text == "Ø" || result.Text == "C")
            {
                if (p.NOcrLastLowercaseHeight > 3 && targetItem.NikseBitmap.Height - p.NOcrLastLowercaseHeight < 2)
                    result.Text = result.Text.ToLower();
            }
            else if (result.Text == "v" || result.Text == "w" || result.Text == "u" || result.Text == "s" || result.Text == "z" || result.Text == "o" || result.Text == "x" || result.Text == "ø" || result.Text == "c")
            {
                if (p.NOcrLastUppercaseHeight > 3 && p.NOcrLastUppercaseHeight - targetItem.NikseBitmap.Height < 2)
                    result.Text = result.Text.ToUpper();
            }

            if (italic)
                return new CompareMatch(result.Text, true, 0, null, result);
            else
                return new CompareMatch(result.Text, result.Italic, 0, null, result);
        }
        public static NikseBitmap CropTopAndBottom(NikseBitmap bmp, out int topCropping, int maxDifferentPixelsOnLine)
        {
            int startTop = 0;
            int maxTop = bmp.Height - 2;
            if (maxTop > bmp.Height)
            {
                maxTop = bmp.Height;
            }

            for (int y = 0; y < maxTop; y++)
            {
                int difference = 0;
                bool allTransparent = true;
                for (int x = 1; x < bmp.Width - 1; x++)
                {
                    int a = bmp.GetAlpha(x, y);
                    if (a != 0)
                    {
                        difference++;
                        if (difference >= maxDifferentPixelsOnLine)
                        {
                            allTransparent = false;
                            break;
                        }
                    }
                }
                if (!allTransparent)
                {
                    break;
                }

                startTop++;
            }
            if (startTop > 9)
            {
                startTop -= 5; // if top space > 9, then always leave blank 5 pixels on top (so . is not confused with ').
            }

            topCropping = startTop;

            for (int y = bmp.Height - 1; y > 3; y--)
            {
                int difference = 0;
                bool allTransparent = true;
                for (int x = 1; x < bmp.Width - 1; x++)
                {
                    int a = bmp.GetAlpha(x, y);
                    if (a != 0)
                    {
                        difference++;
                        if (difference >= maxDifferentPixelsOnLine)
                        {
                            allTransparent = false;
                            break;
                        }
                    }
                }
                if (allTransparent == false)
                {
                    return bmp.CopyRectangle(new Rectangle(0, startTop, bmp.Width - 1, y - startTop + 1));
                }
            }
            return bmp;
        }
Beispiel #23
0
        internal CompareMatch GetNOcrCompareMatch(ImageSplitterItem targetItem, NikseBitmap parentBitmap, NOcrDb nOcrDb, double unItalicFactor, bool tryItalicScaling, bool deepSeek)
        {
            bool italic;
            var expandedResult = NOcrFindExpandedMatch(parentBitmap, targetItem, targetItem.Y - targetItem.ParentY, nOcrDb.OcrCharacters);
            if (expandedResult != null)
                return new CompareMatch(expandedResult.Text, expandedResult.Italic, expandedResult.ExpandCount, null, expandedResult);

            var result = NOcrFindBestMatchNew(parentBitmap, targetItem, targetItem.Y - targetItem.ParentY, out italic, nOcrDb, unItalicFactor, tryItalicScaling, deepSeek);
            if (result == null)
            {
                if (checkBoxNOcrCorrect.Checked)
                    return null;
                else
                    return new CompareMatch("*", false, 0, null);
            }

            // Fix uppercase/lowercase issues (not I/l)
            if (result.Text == "e")
                _nocrLastLowercaseHeight = targetItem.NikseBitmap.Height;
            else if (_nocrLastLowercaseHeight == -1 && result.Text == "a")
                _nocrLastLowercaseHeight = targetItem.NikseBitmap.Height;

            if (result.Text == "E" || result.Text == "H" || result.Text == "R" || result.Text == "D" || result.Text == "T")
                _nocrLastUppercaseHeight = targetItem.NikseBitmap.Height;
            else if (_nocrLastUppercaseHeight == -1 && result.Text == "M")
                _nocrLastUppercaseHeight = targetItem.NikseBitmap.Height;

            if (result.Text == "V" || result.Text == "W" || result.Text == "U" || result.Text == "S" || result.Text == "Z" || result.Text == "O" || result.Text == "X" || result.Text == "Ø" || result.Text == "C")
            {
                if (_nocrLastLowercaseHeight > 3 && targetItem.NikseBitmap.Height - _nocrLastLowercaseHeight < 2)
                    result.Text = result.Text.ToLower();
            }
            else if (result.Text == "v" || result.Text == "w" || result.Text == "u" || result.Text == "s" || result.Text == "z" || result.Text == "o" || result.Text == "x" || result.Text == "ø" || result.Text == "c")
            {
                if (_nocrLastUppercaseHeight > 3 && _nocrLastUppercaseHeight - targetItem.NikseBitmap.Height < 2)
                    result.Text = result.Text.ToUpper();
            }

            if (italic)
                return new CompareMatch(result.Text, true, 0, null, result);
            else
                return new CompareMatch(result.Text, result.Italic, 0, null, result);
        }
        public static List<ImageSplitterItem> SplitBitmapToLettersNew(NikseBitmap bmp, int xOrMorePixelsMakesSpace, bool rightToLeft, bool topToBottom, int minLineHeight)
        {
            var list = new List<ImageSplitterItem>();

            // split into seperate lines
            List<ImageSplitterItem> verticalBitmaps = SplitVertical(bmp, minLineHeight);

            if (!topToBottom)
                verticalBitmaps.Reverse();

            // split into letters
            int lineCount = 0;
            foreach (ImageSplitterItem b in verticalBitmaps)
            {
                if (lineCount > 0)
                    list.Add(new ImageSplitterItem(Environment.NewLine));
                var line = new List<ImageSplitterItem>();
                foreach (ImageSplitterItem item in SplitHorizontalNew(b, xOrMorePixelsMakesSpace))
                {
                    item.ParentY = item.Y;
                    line.Add(item);
                }
                if (rightToLeft)
                    line.Reverse();
                foreach (ImageSplitterItem item in line)
                    list.Add(item);
                lineCount++;
            }

            return list;
        }
        private void TrainLetter(ref int numberOfCharactersLeaned, ref int numberOfCharactersSkipped, NOcrDb nOcrD, List<string> charactersLearned, string s, bool bold)
        {
            Bitmap bmp = GenerateImageFromTextWithStyle(s, bold);
            var nbmp = new NikseBitmap(bmp);
            nbmp.MakeTwoColor(210, 280);
            var list = NikseBitmapImageSplitter.SplitBitmapToLettersNew(nbmp, 10, false, false, 25);
            if (list.Count == 1)
            {
                NOcrChar match = nOcrD.GetMatch(list[0].NikseBitmap);
                if (match == null)
                {

                    pictureBox1.Image = list[0].NikseBitmap.GetBitmap();
                    this.Refresh();
                    Application.DoEvents();
                    System.Threading.Thread.Sleep(100);

                    NOcrChar nOcrChar = new NOcrChar(s);
                    nOcrChar.Width = list[0].NikseBitmap.Width;
                    nOcrChar.Height = list[0].NikseBitmap.Height;
                    VobSubOcrNOcrCharacter.GenerateLineSegments((int)numericUpDownSegmentsPerCharacter.Value, checkBoxVeryAccurate.Checked, nOcrChar, list[0].NikseBitmap);
                    nOcrD.Add(nOcrChar);

                    charactersLearned.Add(s);
                    numberOfCharactersLeaned++;
                    labelInfo.Text = string.Format("Now training font '{1}', total characters leaned is {0}, {2} skipped", numberOfCharactersLeaned, _subtitleFontName, numberOfCharactersSkipped);
                    bmp.Dispose();
                }
                else
                {
                    numberOfCharactersSkipped++;
                }
            }
        }
        private static List<Point> IsVerticalLineTransparetNew(NikseBitmap bmp, int x, out bool right, out bool clean)
        {
            right = false;
            bool left = false;
            clean = true;
            var points = new List<Point>();
            int y = 0;
            while (y < bmp.Height)
            {
                if (bmp.GetAlpha(x, y) > 100)
                {
                    clean = false;
                    if (x == 0)
                        return null;

                    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 if (x > 0 && bmp.GetAlpha(x - 1, y) == 0)
                        {
                            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);
                    }
                    else if (y > 5 && bmp.GetAlpha(x - 1, y - 2) == 0)
                    {
                        x--;
                        y -= 2;
                        left = true;
                        while (points.Count > 0 && points[points.Count - 1].Y > y)
                            points.RemoveAt(points.Count - 1);
                    }
                    else
                    {
                        return null;
                    }

                    if (left && right)
                        return null;
                }
                else
                {
                    points.Add(new Point(x, y));
                    y++;
                }
            }
            return points;
        }
        public static List<ImageSplitterItem> SplitVertical(NikseBitmap bmp, int minLineHeight)
        { // split into lines
            int startY = 0;
            int size = 0;
            var parts = new List<ImageSplitterItem>();
            for (int y = 0; y < bmp.Height; y++)
            {
                bool allTransparent = true;
                for (int x = 0; x < bmp.Width; x++)
                {
                    int a = bmp.GetAlpha(x, y);
                    if (a != 0)
                    {
                        allTransparent = false;
                        break;
                    }
                }
                if (allTransparent)
                {
                    if (size > 2 && size <= minLineHeight)
                    {
                        size++; // at least 'lineMinHeight' pixels, like top of 'i'
                    }
                    else
                    {
                        if (size > 2)
                        {
                            NikseBitmap part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, size + 1));
                            //                            part.Save("c:\\line_0_to_width.bmp");
                            parts.Add(new ImageSplitterItem(0, startY, part));
                            //                            bmp.Save("c:\\original.bmp");
                        }
                        size = 0;
                        startY = y;
                    }
                }
                else
                {
                    size++;
                }

            }
            if (size > 2)
            {
                if (size == bmp.Height)
                {
                    if (size > 100)
                        return SplitVerticalTransparentOrBlack(bmp);
                    else
                        parts.Add(new ImageSplitterItem(0, startY, bmp));
                }
                else
                {
                    parts.Add(new ImageSplitterItem(0, startY, bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, size + 1))));
                }
            }
            return parts;
        }
        internal static unsafe int IsBitmapsAlike(NikseBitmap bmp1, ManagedBitmap bmp2)
        {
            int different = 0;
            int maxDiff = bmp1.Width * bmp1.Height / 5;

            for (int x = 1; x < bmp1.Width; x++)
            {
                for (int y = 1; y < bmp1.Height; y++)
                {
                    if (!IsColorClose(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y), 20))
                        different++;
                }
                if (different > maxDiff)
                    return different + 10;
            }
            return different;
        }
        private static bool IsCursiveVerticalLineTransparent(NikseBitmap bmp, int size, int y, int x, List<Point> cursivePoints)
        {
            bool cursiveOk = true;
            int newY = y;
            int newX = x;
            while (cursiveOk && newY < bmp.Height - 1)
            {
                Color c0 = bmp.GetPixel(newX, newY);
                if (c0.A == 0 || IsColorClose(c0, Color.Black, 280))
                {
                    newY++;
                }
                else
                {
                    byte[] c1 = bmp.GetPixelColors(newX - 1, newY - 1);
                    byte[] c2 = bmp.GetPixelColors(newX - 1, newY);
                    if ((c1[0] == 0 || IsColorClose(c1[0], c1[1], c1[2], c1[3], Color.Black, 280)) && // still dark color...
                        (c2[0] == 0 || IsColorClose(c2[0], c2[1], c2[2], c2[3], Color.Black, 280)))
                    {
                        cursivePoints.Add(new Point(newX, newY));
                        if (newX > 1)
                            newX--;
                        else
                            cursiveOk = false;

                        newY++;
                    }
                    else
                    {
                        cursiveOk = false;
                    }
                }

                if (newX < x - size)
                    cursiveOk = false;
            }
            return cursiveOk;
        }
        private static List <Point> IsVerticalLineTransparetNew(NikseBitmap bmp, int x, out bool right, out bool clean)
        {
            right = false;
            bool left       = false;
            int  leftCount  = 0;
            int  rightCount = 0;

            clean = true;
            var points   = new List <Point>();
            int y        = 0;
            int maxSlide = bmp.Height / 4;

            while (y < bmp.Height)
            {
                if (bmp.GetAlpha(x, y) > 100)
                {
                    clean = false;
                    if (x == 0)
                    {
                        return(null);
                    }

                    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 if (x > 0 && bmp.GetAlpha(x - 1, y) == 0)
                        {
                            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
                        }
                        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);
                        }
                    }
                    else if (y > 5 && bmp.GetAlpha(x - 1, y - 2) == 0)
                    {
                        x--;
                        y   -= 2;
                        left = true;
                        while (points.Count > 0 && points[points.Count - 1].Y > y)
                        {
                            points.RemoveAt(points.Count - 1);
                        }
                    }
                    else
                    {
                        return(null);
                    }

                    if (left)
                    {
                        leftCount++;
                    }

                    if (right)
                    {
                        rightCount++;
                    }

                    if (leftCount > maxSlide || rightCount > maxSlide)
                    {
                        return(null);
                    }
                }
                else
                {
                    points.Add(new Point(x, y));
                    y++;
                }
            }
            return(points);
        }
 private static bool IsVerticalLineTransparentAlphaOnly(NikseBitmap bmp, ref int y, int x)
 {
     bool allTransparent = true;
     for (y = 0; y < bmp.Height - 1; y++)
     {
         int a = bmp.GetAlpha(x, y);
         if (a == 0) // still dark color...
         {
         }
         else
         {
             allTransparent = false;
             break;
         }
     }
     return allTransparent;
 }
        /// <summary>
        /// split into lines
        /// </summary>
        public static List<ImageSplitterItem> SplitToLinesNew(ImageSplitterItem item, int minLineHeight, double averageLineHeight = -1)
        {
            var bmp = new NikseBitmap(item.NikseBitmap);
            var parts = new List<ImageSplitterItem>();
            bool started = false;
            var splitLines = new Dictionary<int, List<Point>>();
            var startY = 0;
            for (int y = minLineHeight; y < bmp.Height - minLineHeight; y++)
            {
                if (startY == y && bmp.IsLineTransparent(y))
                {
                    startY++;
                    continue;
                }

                var points = new List<Point>();
                var yChange = 0;
                var completed = false;
                var backJump = 0;
                int x = 0;
                var maxUp = Math.Min(10, minLineHeight / 2);
                while (x < bmp.Width)
                {
                    var a1 = bmp.GetAlpha(x, y + yChange);
                    var a2 = bmp.GetAlpha(x, y + 1 + yChange);
                    if (a1 > 150 || a2 > 150)
                    {
                        if (x > 1 && yChange < 8 && y + 3 + yChange < bmp.Height &&
                            bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 &&
                            bmp.GetAlpha(x - 1, y + 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 &&
                            bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 &&
                            bmp.GetAlpha(x, y + 2 + yChange) < 150 && bmp.GetAlpha(x, y + 3 + yChange) < 150)
                        {
                            yChange += 2;
                        }

                        else if (x > 1 && yChange < 8 && y + 4 + yChange < bmp.Height &&
                                 bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y + 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 4 + yChange) < 150 &&
                                 bmp.GetAlpha(x, y + 3 + yChange) < 150 && bmp.GetAlpha(x, y + 4 + yChange) < 150)
                        {
                            yChange += 3;
                        }

                        else if (x > 1 && yChange < 7 && y + 5 + yChange < bmp.Height &&
                                 bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y + 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 4 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y + 4 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 5 + yChange) < 150 &&
                                 bmp.GetAlpha(x, y + 4 + yChange) < 150 && bmp.GetAlpha(x, y + 5 + yChange) < 150)
                        {
                            yChange += 4;
                        }

                        else if (x > 1 && yChange > -7 &&
                                 bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y - 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 &&
                                 bmp.GetAlpha(x, y - 2 + yChange) < 150 && bmp.GetAlpha(x, y - 3 + yChange) < 150)
                        {
                            yChange -= 2;
                        }

                        else if (x > 1 && yChange > -7 &&
                                 bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y - 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 4 + yChange) < 150 &&
                                 bmp.GetAlpha(x, y - 3 + yChange) < 150 && bmp.GetAlpha(x, y - 4 + yChange) < 150)
                        {
                            yChange -= 3;
                        }

                        else if (x > 1 && yChange > -7 &&
                                 bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y - 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 4 + yChange) < 150 &&
                                 bmp.GetAlpha(x - 1, y - 4 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 5 + yChange) < 150 &&
                                 bmp.GetAlpha(x, y - 4 + yChange) < 150 && bmp.GetAlpha(x, y - 5 + yChange) < 150)
                        {
                            yChange -= 4;
                        }

                        else if (x > 10 && backJump < 3 && x > 5 && yChange > -7) // go left + up + check 12 pixels right
                        {
                            var done = false;
                            for (int i = 1; i < maxUp; i++)
                            {
                                for (int k = 1; k < 9; k++)
                                {
                                    if (CanGoUpAndRight(bmp, i, 12, x - k, y + yChange, minLineHeight))
                                    {
                                        backJump++;
                                        x -= k;
                                        points.RemoveAll(p => p.X > x);
                                        done = true;
                                        yChange -= (i + 1);
                                        break;
                                    }
                                }

                                if (done)
                                {
                                    break;
                                }
                            }

                            if (!done)
                            {
                                started = true;
                                break;
                            }
                        }

                        else
                        {
                            started = true;
                            break;
                        }
                    }

                    if (started)
                    {
                        points.Add(new Point(x, y + yChange));
                    }

                    completed = x == bmp.Width - 1;
                    x++;
                }

                if (completed)
                {
                    splitLines.Add(y, points);
                }

            }

            var transparentColor = Color.FromArgb(0, 0, 0, 0);
            foreach (var line in splitLines)
            {
                var key = line.Key;
                if (key - startY > minLineHeight && line.Value.Count > 0)
                {
                    var maxY = line.Value.Max(p => p.Y);
                    var part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, maxY - startY));
                    //part.GetBitmap().Save(@"j:\temp\split_" + parts.Count + "_before.bmp");

                    foreach (var point in line.Value)
                    {
                        // delete down
                        for (var y = point.Y - 1; y < startY + part.Height; y++)
                        {
                            part.SetPixel(point.X, y - startY, transparentColor);
                        }
                    }
                    //part.GetBitmap().Save(@"j:\temp\split_" + parts.Count + "_after.bmp");

                    if (!part.IsImageOnlyTransparent() && part.GetNonTransparentHeight() >= minLineHeight)
                    {
                        var minY = line.Value.Min(p => p.Y);
                        // bmp.GetBitmap().Save(@"j:\temp\main_" + parts.Count + "_before.bmp");
                        foreach (var point in line.Value)
                        {
                            // delete up
                            for (var y = point.Y; y >= minY; y--)
                            {
                                bmp.SetPixel(point.X, y, transparentColor);
                            }
                        }
                        // bmp.GetBitmap().Save(@"j:\temp\main_" + parts.Count + "_after.bmp");

                        //    part.GetBitmap().Save(@"j:\temp\split_" + parts.Count + "_after.bmp");
                        var croppedTop = part.CropTopTransparent(0);
                        parts.Add(new ImageSplitterItem(0 + item.X, startY + croppedTop + item.Y, part));

                        startY = key + 1;
                    }

                }
            }

            if (bmp.Height - startY > 1 && parts.Count > 0)
            {
                var part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, bmp.Height - startY));
                if (!part.IsImageOnlyTransparent())
                {
                    //part.GetBitmap().Save(@"j:\temp\split_" + parts.Count + ".bmp");
                    var croppedTop = part.CropTopTransparent(0);
                    parts.Add(new ImageSplitterItem(0 + item.X, startY + croppedTop + item.Y, part));
                }
            }

            if (parts.Count <= 1)
            {
                return new List<ImageSplitterItem> { item };
            }

            return parts;
        }
        private static IEnumerable<ImageSplitterItem> SplitHorizontalNew(ImageSplitterItem lineSplitterItem, int xOrMorePixelsMakesSpace)
        {
            var bmp = new NikseBitmap(lineSplitterItem.NikseBitmap);
            bmp.AddTransparentLineRight();
            var parts = new List<ImageSplitterItem>();
            int startX = 0;
            int width = 0;
            int spacePixels = 0;
            int subtractSpacePixels = 0;
            for (int x = 0; x < bmp.Width; x++)
            {
                bool right;
                bool clean;
                List<Point> points = IsVerticalLineTransparetNew(bmp, x, out right, out clean);

                if (points != null && clean)
                {
                    spacePixels++;
                }

                if (right && points != null)
                {
                    int add = FindMaxX(points, x) - x;
                    width = width + add;
                    subtractSpacePixels = add;
                }

                if (points == null)
                {
                    width++;
                }
                else if (width > 1)
                {
                    var bmp0 = new NikseBitmap(bmp);
                    // remove pixels after current;
                    int k = 0;
                    foreach (Point p in points)
                    {
                        bmp0.MakeVerticalLinePartTransparent(p.X, p.X + k, p.Y);
                        k++;
                    }
                    width = FindMaxX(points, x) - startX;
                    width++;
                    NikseBitmap b1 = bmp0.CopyRectangle(new Rectangle(startX, 0, width, bmp.Height));

                    if (spacePixels >= xOrMorePixelsMakesSpace && parts.Count > 0)
                        parts.Add(new ImageSplitterItem(" "));

                    int addY;
                    b1 = CropTopAndBottom(b1, out addY);
                    parts.Add(new ImageSplitterItem(startX + lineSplitterItem.X, addY + lineSplitterItem.Y, b1)); //y is what?

                    // remove pixels before next letter;
                    int begin = 0;
                    foreach (Point p in points)
                    {
                        bmp.MakeVerticalLinePartTransparent(begin, p.X, p.Y);
                    }
                    width = 1;
                    startX = FindMinX(points, x);
                    spacePixels = -subtractSpacePixels;
                    subtractSpacePixels = 0;
                }
                else
                {
                    width = 1;
                    startX = FindMinX(points, x);
                }
            }
            return parts;
        }
Beispiel #34
0
        /// <summary>
        /// Ocr via image compare
        /// </summary>
        private string SplitAndOcrBitmapNormalNew(Bitmap bitmap, int listViewIndex)
        {
            if (_ocrFixEngine == null)
                LoadOcrFixEngine(null, LanguageString);

            string threadText = null;
            //if (_icThreadResults != null && !string.IsNullOrEmpty(_icThreadResults[listViewIndex]))
            //    threadText = _icThreadResults[listViewIndex];

            string line = string.Empty;
            if (threadText == null)
            {
                var matches = new List<CompareMatch>();
                var parentBitmap = new NikseBitmap(bitmap);
                int minLineHeight = _binOcrLastLowercaseHeight - 3;
                if (minLineHeight < 5)
                    minLineHeight = _nocrLastLowercaseHeight;
                if (minLineHeight < 5)
                    minLineHeight = 6;
                List<ImageSplitterItem> list = NikseBitmapImageSplitter.SplitBitmapToLettersNew(parentBitmap, (int)numericUpDownPixelsIsSpace.Value, checkBoxRightToLeft.Checked, Configuration.Settings.VobSubOcr.TopToBottom, minLineHeight);
                int index = 0;
                bool expandSelection = false;
                bool shrinkSelection = false;
                var expandSelectionList = new List<ImageSplitterItem>();
                while (index < list.Count)
                {
                    ImageSplitterItem item = list[index];
                    if (expandSelection || shrinkSelection)
                    {
                        expandSelection = false;
                        if (shrinkSelection && index > 0)
                        {
                            shrinkSelection = false;
                        }
                        else if (index + 1 < list.Count && list[index + 1].NikseBitmap != null) // only allow expand to EndOfLine or space
                        {

                            index++;
                            expandSelectionList.Add(list[index]);
                        }
                        item = GetExpandedSelectionNew(parentBitmap, expandSelectionList);

                        _vobSubOcrCharacter.Initialize(bitmap, item, _manualOcrDialogPosition, _italicCheckedLast, expandSelectionList.Count > 1, null, _lastAdditions, this);
                        DialogResult result = _vobSubOcrCharacter.ShowDialog(this);
                        _manualOcrDialogPosition = _vobSubOcrCharacter.FormPosition;
                        if (result == DialogResult.OK && _vobSubOcrCharacter.ShrinkSelection)
                        {
                            shrinkSelection = true;
                            index--;
                            if (expandSelectionList.Count > 0)
                                expandSelectionList.RemoveAt(expandSelectionList.Count - 1);
                        }
                        else if (result == DialogResult.OK && _vobSubOcrCharacter.ExpandSelection)
                        {
                            expandSelection = true;
                        }
                        else if (result == DialogResult.OK)
                        {
                            string text = _vobSubOcrCharacter.ManualRecognizedCharacters;
                            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));
                            expandSelectionList = new List<ImageSplitterItem>();
                        }
                        else if (result == DialogResult.Abort)
                        {
                            _abort = true;
                        }
                        else
                        {
                            matches.Add(new CompareMatch("*", false, 0, null));
                        }
                        _italicCheckedLast = _vobSubOcrCharacter.IsItalic;

                    }
                    else if (item.NikseBitmap == null)
                    {
                        matches.Add(new CompareMatch(item.SpecialCharacter, false, 0, null));
                    }
                    else
                    {
                        CompareMatch bestGuess;
                        CompareMatch match = GetCompareMatchNew(item, parentBitmap, out bestGuess, list, index);
                        if (match == null) // Try line ocr if no image compare match
                        {
                            if (_nOcrDb != null && _nOcrDb.OcrCharacters.Count > 0)
                                match = GetNOcrCompareMatchNew(item, parentBitmap, _nOcrDb, _unItalicFactor, true, true);
                        }

                        if (match == null)
                        {
                            _vobSubOcrCharacter.Initialize(bitmap, item, _manualOcrDialogPosition, _italicCheckedLast, false, bestGuess, _lastAdditions, this);
                            DialogResult result = _vobSubOcrCharacter.ShowDialog(this);
                            _manualOcrDialogPosition = _vobSubOcrCharacter.FormPosition;
                            if (result == DialogResult.OK && _vobSubOcrCharacter.ExpandSelection)
                            {
                                expandSelectionList.Add(item);
                                expandSelection = true;
                            }
                            else if (result == DialogResult.OK)
                            {
                                string text = _vobSubOcrCharacter.ManualRecognizedCharacters;
                                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));
                                SetBinOcrLowercaseUppercase(item.NikseBitmap.Height, text);
                            }
                            else if (result == DialogResult.Abort)
                            {
                                _abort = true;
                            }
                            else
                            {
                                matches.Add(new CompareMatch("*", false, 0, null));
                            }
                            _italicCheckedLast = _vobSubOcrCharacter.IsItalic;
                        }
                        else // found image match
                        {
                            matches.Add(new CompareMatch(match.Text, match.Italic, 0, null));
                            if (match.ExpandCount > 0)
                                index += match.ExpandCount - 1;
                        }
                    }
                    if (_abort)
                        return string.Empty;
                    if (!expandSelection && !shrinkSelection)
                        index++;
                    if (shrinkSelection && expandSelectionList.Count < 2)
                    {
                        shrinkSelection = false;
                        expandSelectionList = new List<ImageSplitterItem>();
                    }
                }

                line = GetStringWithItalicTags(matches);
            }
            else
            {
                line = threadText;
            }
            if (checkBoxAutoFixCommonErrors.Checked)
                line = OcrFixEngine.FixOcrErrorsViaHardcodedRules(line, _lastLine, null); // TODO: add abbreviations list

            if (checkBoxRightToLeft.Checked)
                line = ReverseNumberStrings(line);

            //ocr fix engine
            string textWithOutFixes = line;
            if (_ocrFixEngine.IsDictionaryLoaded)
            {
                if (checkBoxAutoFixCommonErrors.Checked)
                    line = _ocrFixEngine.FixOcrErrors(line, listViewIndex, _lastLine, true, checkBoxGuessUnknownWords.Checked);
                int correctWords;
                int wordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(line, out correctWords);

                if (wordsNotFound > 0 || correctWords == 0 || textWithOutFixes != null && textWithOutFixes.ToString().Replace("~", string.Empty).Trim().Length == 0)
                {
                    _ocrFixEngine.AutoGuessesUsed.Clear();
                    _ocrFixEngine.UnknownWordsFound.Clear();
                    line = _ocrFixEngine.FixUnknownWordsViaGuessOrPrompt(out wordsNotFound, line, listViewIndex, bitmap, checkBoxAutoFixCommonErrors.Checked, checkBoxPromptForUnknownWords.Checked, true, checkBoxGuessUnknownWords.Checked);
                }

                if (_ocrFixEngine.Abort)
                {
                    ButtonStopClick(null, null);
                    _ocrFixEngine.Abort = false;
                    return string.Empty;
                }

                // Log used word guesses (via word replace list)
                foreach (string guess in _ocrFixEngine.AutoGuessesUsed)
                    listBoxLogSuggestions.Items.Add(guess);
                _ocrFixEngine.AutoGuessesUsed.Clear();

                // Log unkown words guess (found via spelling dictionaries)
                LogUnknownWords();

                if (wordsNotFound >= 3)
                    subtitleListView1.SetBackgroundColor(listViewIndex, Color.Red);
                if (wordsNotFound == 2)
                    subtitleListView1.SetBackgroundColor(listViewIndex, Color.Orange);
                else if (wordsNotFound == 1)
                    subtitleListView1.SetBackgroundColor(listViewIndex, Color.Yellow);
                else if (line.Trim().Length == 0)
                    subtitleListView1.SetBackgroundColor(listViewIndex, Color.Orange);
                else
                    subtitleListView1.SetBackgroundColor(listViewIndex, Color.LightGreen);
            }

            if (textWithOutFixes.Trim() != line.Trim())
            {
                _tesseractOcrAutoFixes++;
                labelFixesMade.Text = string.Format(" - {0}", _tesseractOcrAutoFixes);
                LogOcrFix(listViewIndex, textWithOutFixes.ToString(), line);
            }

            return line;
        }
Beispiel #35
0
        private string Tesseract3DoOcrViaExe(Bitmap bmp, string language, string psmMode)
        {
            // change yellow color to white - easier for Tesseract
            var nbmp = new NikseBitmap(bmp);
            nbmp.ReplaceYellowWithWhite(); // optimized replace
            bool useHocr = true;

            string tempTiffFileName = Path.GetTempPath() + Guid.NewGuid().ToString() + ".png";
            var b = nbmp.GetBitmap();
            b.Save(tempTiffFileName, System.Drawing.Imaging.ImageFormat.Png);
            string tempTextFileName = Path.GetTempPath() + Guid.NewGuid().ToString();
            b.Dispose();

            var process = new Process();
            process.StartInfo = new ProcessStartInfo(Configuration.TesseractFolder + "tesseract.exe");
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.Arguments = "\"" + tempTiffFileName + "\" \"" + tempTextFileName + "\" -l " + language;

            if (checkBoxTesseractMusicOn.Checked)
                process.StartInfo.Arguments += "+music";

            if (!string.IsNullOrEmpty(psmMode))
                process.StartInfo.Arguments += " " + psmMode.Trim();

            if (useHocr)
                process.StartInfo.Arguments += " hocr";
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            if (Utilities.IsRunningOnLinux() || Utilities.IsRunningOnMac())
            {
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardError = true;
                process.StartInfo.FileName = "tesseract";
            }
            else
            {
                process.StartInfo.WorkingDirectory = (Configuration.TesseractFolder);
            }

            try
            {
                process.Start();
            }
            catch
            {
                MessageBox.Show("Unable to start 'tesseract' - make sure tesseract-ocr 3.x is installed!");
                throw;
            }
            process.WaitForExit(5000);

            string result = string.Empty;
            if (useHocr)
            {
                string outputFileName = tempTextFileName + ".html";
                try
                {
                    if (File.Exists(outputFileName))
                    {
                        result = File.ReadAllText(outputFileName);
                        result = ParseHocr(result);
                        File.Delete(outputFileName);
                    }
                    File.Delete(tempTiffFileName);
                }
                catch
                {
                }
            }
            else
            {
                string outputFileName = tempTextFileName + ".txt";
                try
                {
                    if (File.Exists(outputFileName))
                    {
                        result = File.ReadAllText(outputFileName);
                        File.Delete(outputFileName);
                    }
                    File.Delete(tempTiffFileName);
                }
                catch
                {
                }
            }
            return result;
        }
Beispiel #36
0
 public ImageCompareAddition(string name, string text, NikseBitmap image, bool italic, int index)
 {
     Name = name;
     Text = text;
     Image = image;
     Text = text;
     Italic = italic;
     Index = index;
 }
        internal static unsafe int IsBitmapsAlike(NikseBitmap bmp1, Ocr.Binary.BinaryOcrBitmap bmp2)
        {
            int different = 0;
            int maxDiff = bmp1.Width * bmp1.Height / 5;

            for (int x = 1; x < bmp1.Width; x++)
            {
                for (int y = 1; y < bmp1.Height; y++)
                {
                    if (bmp1.GetAlpha(x, y) < 100 && bmp2.GetPixel(x, y) > 0)
                        different++;
                }
                if (different > maxDiff)
                    return different + 10;
            }
            return different;
        }
        private static IEnumerable <ImageSplitterItem> SplitHorizontalNew(ImageSplitterItem lineSplitterItem, int xOrMorePixelsMakesSpace)
        {
            var bmp = new NikseBitmap(lineSplitterItem.NikseBitmap);

            bmp.AddTransparentLineRight();
            var parts               = new List <ImageSplitterItem>();
            int startX              = 0;
            int width               = 0;
            int spacePixels         = 0;
            int subtractSpacePixels = 0;

            for (int x = 0; x < bmp.Width; x++)
            {
                bool         right;
                bool         clean;
                List <Point> points = IsVerticalLineTransparetNew(bmp, x, out right, out clean);

                if (points != null && clean)
                {
                    spacePixels++;
                }

                if (right && points != null)
                {
                    int add = FindMaxX(points, x) - x;
                    width += add;
                    subtractSpacePixels = add;
                }

                var newStartX = points != null?FindMinX(points, x) : 0;

                if (points == null)
                {
                    width++;
                }
                else if (width > 0 && newStartX > startX + 1)
                {
                    var bmp0 = new NikseBitmap(bmp);
                    // remove pixels after current;
                    for (int index = 0; index < points.Count; index++)
                    {
                        var p = points[index];
                        bmp0.MakeVerticalLinePartTransparent(p.X, p.X + index, p.Y);
                    }
                    width = FindMaxX(points, x) - startX;
                    width--;
                    startX++;
                    var b1 = bmp0.CopyRectangle(new Rectangle(startX, 0, width, bmp.Height));

                    int addY;
                    b1 = CropTopAndBottom(b1, out addY);

                    if (spacePixels >= xOrMorePixelsMakesSpace && parts.Count > 0)
                    {
                        parts.Add(new ImageSplitterItem(" ")
                        {
                            Y = addY + lineSplitterItem.Y
                        });
                    }

                    if (b1.Width > 0 && b1.Height > 0)
                    {
                        parts.Add(new ImageSplitterItem(startX + lineSplitterItem.X, addY + lineSplitterItem.Y, b1)); //y is what?
                    }

                    // remove pixels before next letter;
                    const int begin = 0;
                    foreach (var p in points)
                    {
                        bmp.MakeVerticalLinePartTransparent(begin, p.X, p.Y);
                    }
                    width               = 1;
                    startX              = FindMinX(points, x);
                    spacePixels         = -subtractSpacePixels;
                    subtractSpacePixels = 0;
                }
                else if (clean)
                {
                    width  = 1;
                    startX = newStartX;
                }
            }
            return(parts);
        }