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 Bitmap ToOldBitmap() { NikseBitmap nbmp = new NikseBitmap(Width, Height); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { nbmp.SetPixel(x, y, this.GetPixel(x, y)); } } return(nbmp.GetBitmap()); }
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(); }
private string OcrViaTesseract(Bitmap bitmap, int index) { if (bitmap == null) return string.Empty; if (_ocrFixEngine == null) comboBoxDictionaries_SelectedIndexChanged(null, null); int badWords = 0; string textWithOutFixes; if (!string.IsNullOrEmpty(_tesseractAsyncStrings[index])) { textWithOutFixes = _tesseractAsyncStrings[index]; } else { if (_tesseractAsyncIndex <= index) _tesseractAsyncIndex = index + 10; textWithOutFixes = Tesseract3DoOcrViaExe(bitmap, _languageId, "-psm 6"); // 6 = Assume a single uniform block of text. } if ((!textWithOutFixes.Contains(Environment.NewLine) || Utilities.CountTagInText("\n", textWithOutFixes) > 2) && (textWithOutFixes.Length < 17 || bitmap.Height < 50)) { string psm = Tesseract3DoOcrViaExe(bitmap, _languageId, "-psm 7"); // 7 = Treat the image as a single text line. if (textWithOutFixes != psm) { if (textWithOutFixes.Trim().Length == 0) { textWithOutFixes = psm; } else if (psm.Length > textWithOutFixes.Length) { if (!psm.Contains("9") && textWithOutFixes.Contains("9") || !psm.Contains("6") && textWithOutFixes.Contains("6") || !psm.Contains("5") && textWithOutFixes.Contains("5") || !psm.Contains("3") && textWithOutFixes.Contains("3") || !psm.Contains("1") && textWithOutFixes.Contains("1") || !psm.Contains("$") && textWithOutFixes.Contains("$") || !psm.Contains("•") && textWithOutFixes.Contains("•") || !psm.Contains("Y") && textWithOutFixes.Contains("Y") || !psm.Contains("'") && textWithOutFixes.Contains("'") || !psm.Contains("€") && textWithOutFixes.Contains("€")) textWithOutFixes = psm; } else if (psm.Length == textWithOutFixes.Length && (!psm.Contains("0") && textWithOutFixes.Contains("0") || // these chars are often mistaken !psm.Contains("9") && textWithOutFixes.Contains("9") || !psm.Contains("8") && textWithOutFixes.Contains("8") || !psm.Contains("5") && textWithOutFixes.Contains("5") || !psm.Contains("3") && textWithOutFixes.Contains("3") || !psm.Contains("1") && textWithOutFixes.Contains("1") || !psm.Contains("$") && textWithOutFixes.Contains("$") || !psm.Contains("€") && textWithOutFixes.Contains("€") || !psm.Contains("•") && textWithOutFixes.Contains("•") || !psm.Contains("Y") && textWithOutFixes.Contains("Y") || !psm.Contains("'") && textWithOutFixes.Contains("'") || !psm.Contains("/") && textWithOutFixes.Contains("/") || !psm.Contains("(") && textWithOutFixes.Contains("(") || !psm.Contains(")") && textWithOutFixes.Contains(")") || !psm.Contains("_") && textWithOutFixes.Contains("_"))) { textWithOutFixes = psm; } else if (psm.Length == textWithOutFixes.Length && psm.EndsWith(".") && !textWithOutFixes.EndsWith(".")) { textWithOutFixes = psm; } } } if (!checkBoxTesseractItalicsOn.Checked) textWithOutFixes = textWithOutFixes.Replace("<i>", string.Empty).Replace("</i>", string.Empty); // Sometimes Tesseract has problems with small fonts - it helps to make the image larger if (textWithOutFixes.Replace("<i>", string.Empty).Replace("</i>", string.Empty).Replace("@", string.Empty).Replace("%", string.Empty).Replace("|", string.Empty).Trim().Length < 3 || Utilities.CountTagInText("\n", textWithOutFixes) > 2) { string rs = TesseractResizeAndRetry(bitmap); textWithOutFixes = rs; if (!checkBoxTesseractItalicsOn.Checked) textWithOutFixes = textWithOutFixes.Replace("<i>", string.Empty).Replace("</i>", string.Empty); } // fix italics textWithOutFixes = FixItalics(textWithOutFixes); int numberOfWords = textWithOutFixes.ToString().Split((" " + Environment.NewLine).ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length; string line = textWithOutFixes.ToString().Trim(); if (_ocrFixEngine.IsDictionaryLoaded) { if (checkBoxAutoFixCommonErrors.Checked) line = _ocrFixEngine.FixOcrErrors(line, index, _lastLine, true, checkBoxGuessUnknownWords.Checked); int correctWords; int wordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(line, out correctWords); int oldCorrectWords = correctWords; if (wordsNotFound > 0 || correctWords == 0) { List<string> oldUnkownWords = new List<string>(); oldUnkownWords.AddRange(_ocrFixEngine.UnknownWordsFound); _ocrFixEngine.UnknownWordsFound.Clear(); string newUnfixedText = TesseractResizeAndRetry(bitmap); string newText = _ocrFixEngine.FixOcrErrors(newUnfixedText, index, _lastLine, true, checkBoxGuessUnknownWords.Checked); int newWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(newText, out correctWords); if (wordsNotFound == 1 && newWordsNotFound == 1 && newUnfixedText.EndsWith("!!") && textWithOutFixes.EndsWith("u") && newText.Length > 1) { _ocrFixEngine.UnknownWordsFound.Clear(); newText = textWithOutFixes.Substring(0, textWithOutFixes.Length - 1) + "!!"; newWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(newText, out correctWords); } else if ((!newText.Contains("9") || textWithOutFixes.Contains("9")) && (!newText.Replace("</i>", string.Empty).Contains("/") || textWithOutFixes.Replace("</i>", string.Empty).Contains("/")) && newUnfixedText.Trim().Length > 0 && newWordsNotFound < wordsNotFound || (newWordsNotFound == wordsNotFound && newText.EndsWith("!") && textWithOutFixes.EndsWith("l"))) { wordsNotFound = newWordsNotFound; if (textWithOutFixes.Length > 3 && textWithOutFixes.EndsWith("...") && !newText.EndsWith(".") && !newText.EndsWith(",") && !newText.EndsWith("!") && !newText.EndsWith("?") && !newText.EndsWith("</i>")) newText = newText.TrimEnd() + "..."; else if (textWithOutFixes.Length > 0 && textWithOutFixes.EndsWith(".") && !newText.EndsWith(".") && !newText.EndsWith(",") && !newText.EndsWith("!") && !newText.EndsWith("?") && !newText.EndsWith("</i>")) newText = newText.TrimEnd() + "."; else if (textWithOutFixes.Length > 0 && textWithOutFixes.EndsWith("?") && !newText.EndsWith(".") && !newText.EndsWith(",") && !newText.EndsWith("!") && !newText.EndsWith("?") && !newText.EndsWith("</i>")) newText = newText.TrimEnd() + "?"; textWithOutFixes = newUnfixedText; line = FixItalics(newText); } else if (correctWords > oldCorrectWords + 1 || (correctWords > oldCorrectWords && !textWithOutFixes.Contains(" "))) { wordsNotFound = newWordsNotFound; textWithOutFixes = newUnfixedText; line = newText; } else { _ocrFixEngine.UnknownWordsFound.Clear(); _ocrFixEngine.UnknownWordsFound.AddRange(oldUnkownWords); } } if (wordsNotFound > 0 || correctWords == 0 || textWithOutFixes != null && textWithOutFixes.ToString().Replace("~", string.Empty).Trim().Length < 2) { if (_bluRaySubtitles != null && !line.Contains("<i>")) { _ocrFixEngine.AutoGuessesUsed.Clear(); _ocrFixEngine.UnknownWordsFound.Clear(); // which is best - normal image or one color image? var nbmp = new NikseBitmap(bitmap); nbmp.MakeOneColor(Color.White); Bitmap oneColorBitmap = nbmp.GetBitmap(); string oneColorText = Tesseract3DoOcrViaExe(oneColorBitmap, _languageId, "-psm 6"); // 6 = Assume a single uniform block of text. oneColorBitmap.Dispose(); nbmp = null; if (oneColorText.Length > 1 && !oneColorText.Contains("CD") && (!oneColorText.Contains("0") || line.Contains("0")) && (!oneColorText.Contains("2") || line.Contains("2")) && (!oneColorText.Contains("3") || line.Contains("4")) && (!oneColorText.Contains("5") || line.Contains("5")) && (!oneColorText.Contains("9") || line.Contains("9")) && (!oneColorText.Contains("•") || line.Contains("•")) && (!oneColorText.Contains(")") || line.Contains(")")) && Utilities.CountTagInText(oneColorText, "(") < 2 && Utilities.CountTagInText(oneColorText, ")") < 2 && Utilities.CountTagInText(oneColorText, Environment.NewLine) < 3) { int modiCorrectWords; int modiWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(oneColorText, out modiCorrectWords); string modiTextOcrFixed = oneColorText; if (checkBoxAutoFixCommonErrors.Checked) modiTextOcrFixed = _ocrFixEngine.FixOcrErrors(oneColorText, index, _lastLine, false, checkBoxGuessUnknownWords.Checked); int modiOcrCorrectedCorrectWords; int modiOcrCorrectedWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(modiTextOcrFixed, out modiOcrCorrectedCorrectWords); if (modiOcrCorrectedWordsNotFound <= modiWordsNotFound) { oneColorText = modiTextOcrFixed; modiWordsNotFound = modiOcrCorrectedWordsNotFound; modiCorrectWords = modiOcrCorrectedCorrectWords; } if (modiWordsNotFound < wordsNotFound || (textWithOutFixes.Length == 1 && modiWordsNotFound == 0)) { line = FixItalics(oneColorText); // use one-color text wordsNotFound = modiWordsNotFound; correctWords = modiCorrectWords; if (checkBoxAutoFixCommonErrors.Checked) line = _ocrFixEngine.FixOcrErrors(line, index, _lastLine, true, checkBoxGuessUnknownWords.Checked); } else if (wordsNotFound == modiWordsNotFound && oneColorText.EndsWith("!") && (line.EndsWith("l") || line.EndsWith("fl"))) { line = FixItalics(oneColorText); wordsNotFound = modiWordsNotFound; correctWords = modiCorrectWords; if (checkBoxAutoFixCommonErrors.Checked) line = _ocrFixEngine.FixOcrErrors(line, index, _lastLine, true, checkBoxGuessUnknownWords.Checked); } } } } if (checkBoxTesseractItalicsOn.Checked) { if (line.Contains("<i>") || wordsNotFound > 0 || correctWords == 0 || textWithOutFixes != null && textWithOutFixes.ToString().Replace("~", string.Empty).Trim().Length < 2) { _ocrFixEngine.AutoGuessesUsed.Clear(); _ocrFixEngine.UnknownWordsFound.Clear(); // which is best - normal image or de-italic'ed? We find out here var unItalicedBmp = UnItalic(bitmap, _unItalicFactor); string unItalicText = Tesseract3DoOcrViaExe(unItalicedBmp, _languageId, "-psm 6"); // 6 = Assume a single uniform block of text. unItalicedBmp.Dispose(); if (unItalicText.Length > 1) { int modiCorrectWords; int modiWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(unItalicText, out modiCorrectWords); string modiTextOcrFixed = unItalicText; if (checkBoxAutoFixCommonErrors.Checked) modiTextOcrFixed = _ocrFixEngine.FixOcrErrors(unItalicText, index, _lastLine, false, checkBoxGuessUnknownWords.Checked); int modiOcrCorrectedCorrectWords; int modiOcrCorrectedWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(modiTextOcrFixed, out modiOcrCorrectedCorrectWords); if (modiOcrCorrectedWordsNotFound <= modiWordsNotFound) { unItalicText = modiTextOcrFixed; modiWordsNotFound = modiOcrCorrectedWordsNotFound; modiCorrectWords = modiOcrCorrectedCorrectWords; } bool ok = modiWordsNotFound < wordsNotFound || (textWithOutFixes.Length == 1 && modiWordsNotFound == 0); if (!ok) ok = wordsNotFound == modiWordsNotFound && unItalicText.EndsWith("!") && (line.EndsWith("l") || line.EndsWith("fl")); if (!ok) ok = wordsNotFound == modiWordsNotFound && line.StartsWith("<i>") && line.EndsWith("</i>"); if (ok && Utilities.CountTagInText(unItalicText, "/") > Utilities.CountTagInText(line, "/") + 1) ok = false; if (ok && Utilities.CountTagInText(unItalicText, "\\") > Utilities.CountTagInText(line, "\\")) ok = false; if (ok && Utilities.CountTagInText(unItalicText, ")") > Utilities.CountTagInText(line, ")") + 1) ok = false; if (ok && Utilities.CountTagInText(unItalicText, "(") > Utilities.CountTagInText(line, "(") + 1) ok = false; if (ok && Utilities.CountTagInText(unItalicText, "$") > Utilities.CountTagInText(line, "$") + 1) ok = false; if (ok && Utilities.CountTagInText(unItalicText, "€") > Utilities.CountTagInText(line, "€") + 1) ok = false; if (ok && Utilities.CountTagInText(unItalicText, "•") > Utilities.CountTagInText(line, "•")) ok = false; if (ok) { wordsNotFound = modiWordsNotFound; correctWords = modiCorrectWords; line = line.Replace("<i>", string.Empty).Replace("</i>", string.Empty).Trim(); if (line.Length > 7 && unItalicText.Length > 7 && unItalicText.StartsWith("I ") && line.StartsWith(unItalicText.Remove(0, 2).Substring(0, 4))) unItalicText = unItalicText.Remove(0, 2); if (checkBoxTesseractMusicOn.Checked) { if ((line.StartsWith("J' ") || line.StartsWith("J“ ") || line.StartsWith("J* ") || line.StartsWith("♪ ")) && unItalicText.Length > 3 && unItalicText.Replace("<i>", string.Empty).Replace("</i>", string.Empty).Substring(1, 2) == "' ") { unItalicText = "♪ " + unItalicText.Remove(0, 2).TrimStart(); } if ((line.StartsWith("J' ") || line.StartsWith("J“ ") || line.StartsWith("J* ") || line.StartsWith("♪ ")) && unItalicText.Length > 3 && unItalicText.Replace("<i>", string.Empty).Replace("</i>", string.Empty).Substring(1, 1) == " ") { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = Utilities.RemoveHtmlTags(unItalicText); unItalicText = "♪ " + unItalicText.Remove(0, 2).TrimStart(); if (ita) unItalicText = "<i>" + unItalicText + "</i>"; } if ((line.StartsWith("J' ") || line.StartsWith("J“ ") || line.StartsWith("J* ") || line.StartsWith("♪ ")) && unItalicText.Length > 3 && unItalicText.Replace("<i>", string.Empty).Replace("</i>", string.Empty).Substring(2, 1) == " ") { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = Utilities.RemoveHtmlTags(unItalicText); unItalicText = "♪ " + unItalicText.Remove(0, 2).TrimStart(); if (ita) unItalicText = "<i>" + unItalicText + "</i>"; } if (unItalicText.StartsWith("J'") && (line.StartsWith("♪") || textWithOutFixes.StartsWith("♪") || textWithOutFixes.StartsWith("<i>♪") || unItalicText.EndsWith("♪"))) { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = Utilities.RemoveHtmlTags(unItalicText); unItalicText = "♪ " + unItalicText.Remove(0, 2).TrimStart(); if (ita) unItalicText = "<i>" + unItalicText + "</i>"; } if ((line.StartsWith("J` ") || line.StartsWith("J“ ") || line.StartsWith("J' ") || line.StartsWith("J* ")) && unItalicText.StartsWith("S ")) { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = Utilities.RemoveHtmlTags(unItalicText); unItalicText = "♪ " + unItalicText.Remove(0, 2).TrimStart(); if (ita) unItalicText = "<i>" + unItalicText + "</i>"; } if ((line.StartsWith("J` ") || line.StartsWith("J“ ") || line.StartsWith("J' ") || line.StartsWith("J* ")) && unItalicText.StartsWith("<i>S</i> ")) { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = Utilities.RemoveHtmlTags(unItalicText); unItalicText = "♪ " + unItalicText.Remove(0, 8).TrimStart(); if (ita) unItalicText = "<i>" + unItalicText + "</i>"; } if (unItalicText.StartsWith(";'") && (line.StartsWith("♪") || textWithOutFixes.StartsWith("♪") || textWithOutFixes.StartsWith("<i>♪") || unItalicText.EndsWith("♪"))) { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = Utilities.RemoveHtmlTags(unItalicText); unItalicText = "♪ " + unItalicText.Remove(0, 2).TrimStart(); if (ita) unItalicText = "<i>" + unItalicText + "</i>"; } if (unItalicText.StartsWith(",{*") && (line.StartsWith("♪") || textWithOutFixes.StartsWith("♪") || textWithOutFixes.StartsWith("<i>♪") || unItalicText.EndsWith("♪"))) { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = Utilities.RemoveHtmlTags(unItalicText); unItalicText = "♪ " + unItalicText.Remove(0, 3).TrimStart(); if (ita) unItalicText = "<i>" + unItalicText + "</i>"; } if (unItalicText.EndsWith("J'") && (line.EndsWith("♪") || textWithOutFixes.EndsWith("♪") || textWithOutFixes.EndsWith("♪</i>") || unItalicText.StartsWith("♪"))) { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = Utilities.RemoveHtmlTags(unItalicText); unItalicText = unItalicText.Remove(unItalicText.Length - 3, 2).TrimEnd() + " ♪"; if (ita) unItalicText = "<i>" + unItalicText + "</i>"; } } if (unItalicText.StartsWith("[") && !line.StartsWith("[")) { unItalicText = unItalicText.Remove(0, 1); if (unItalicText.EndsWith("]")) unItalicText = unItalicText.TrimEnd(']'); } if (unItalicText.StartsWith("{") && !line.StartsWith("{")) { unItalicText = unItalicText.Remove(0, 1); if (unItalicText.EndsWith("}")) unItalicText = unItalicText.TrimEnd('}'); } if (unItalicText.EndsWith("}") && !line.EndsWith("}")) unItalicText = unItalicText.TrimEnd('}'); if (line.EndsWith("...") && unItalicText.EndsWith("”!")) unItalicText = unItalicText.TrimEnd('!').TrimEnd('”') + "."; if (line.EndsWith("...") && unItalicText.EndsWith("\"!")) unItalicText = unItalicText.TrimEnd('!').TrimEnd('"') + "."; if (line.EndsWith(".") && !unItalicText.EndsWith(".") && !unItalicText.EndsWith(".</i>")) { string post = string.Empty; if (unItalicText.EndsWith("</i>")) { post = "</i>"; unItalicText = unItalicText.Remove(unItalicText.Length - 4); } if (unItalicText.EndsWith("'") && !line.EndsWith("'.")) unItalicText = unItalicText.TrimEnd('\''); unItalicText += "." + post; } if (unItalicText.EndsWith(".") && !unItalicText.EndsWith("...") && !unItalicText.EndsWith("...</i>") && line.EndsWith("...")) { string post = string.Empty; if (unItalicText.EndsWith("</i>")) { post = "</i>"; unItalicText = unItalicText.Remove(unItalicText.Length - 4); } unItalicText += ".." + post; } if (unItalicText.EndsWith("..") && !unItalicText.EndsWith("...") && !unItalicText.EndsWith("...</i>") && line.EndsWith("...")) { string post = string.Empty; if (unItalicText.EndsWith("</i>")) { post = "</i>"; unItalicText = unItalicText.Remove(unItalicText.Length - 4); } unItalicText += "." + post; } if (line.EndsWith("!") && !unItalicText.EndsWith("!") && !unItalicText.EndsWith("!</i>")) { if (unItalicText.EndsWith("!'")) { unItalicText = unItalicText.TrimEnd('\''); } else { if (unItalicText.EndsWith("l</i>") && _ocrFixEngine != null) { string w = unItalicText.Substring(0, unItalicText.Length - 4); int wIdx = w.Length - 1; while (wIdx >= 0 && !(" .,!?<>:;'-$@£()[]<>/\"".Contains(w[wIdx].ToString()))) { wIdx--; } if (wIdx + 1 < w.Length && unItalicText.Length > 5) { w = w.Substring(wIdx + 1); if (!_ocrFixEngine.DoSpell(w)) unItalicText = unItalicText.Remove(unItalicText.Length - 5, 1); } unItalicText = unItalicText.Insert(unItalicText.Length - 4, "!"); } else if (unItalicText.EndsWith("l") && _ocrFixEngine != null) { string w = unItalicText; int wIdx = w.Length - 1; while (wIdx >= 0 && !(" .,!?<>:;'-$@£()[]<>/\"".Contains(w[wIdx].ToString()))) { wIdx--; } if (wIdx + 1 < w.Length && unItalicText.Length > 5) { w = w.Substring(wIdx + 1); if (!_ocrFixEngine.DoSpell(w)) unItalicText = unItalicText.Remove(unItalicText.Length - 1, 1); } unItalicText += "!"; } else { unItalicText += "!"; } } } if (line.EndsWith("?") && !unItalicText.EndsWith("?") && !unItalicText.EndsWith("?</i>")) { if (unItalicText.EndsWith("?'")) unItalicText = unItalicText.TrimEnd('\''); else unItalicText += "?"; } line = unItalicText.Replace("<i>", string.Empty).Replace("</i>", string.Empty); if (checkBoxAutoFixCommonErrors.Checked) { if (line.Contains("'.") && !textWithOutFixes.Contains("'.") && textWithOutFixes.Contains(":") && !line.EndsWith("'.") && Configuration.Settings.Tools.OcrFixUseHardcodedRules) { line = line.Replace("'.", ":"); } line = _ocrFixEngine.FixOcrErrors(line, index, _lastLine, true, checkBoxGuessUnknownWords.Checked); } line = "<i>" + line + "</i>"; } else { unItalicText = unItalicText.Replace("</i>", string.Empty); if (line.EndsWith("</i>") && unItalicText.EndsWith(".")) { line = line.Remove(line.Length - 4, 4); if (line.EndsWith("-")) line = line.TrimEnd('-') + "."; if (Utilities.AllLetters.Contains(line.Substring(line.Length - 1))) line += "."; line += "</i>"; } } } } } if (checkBoxTesseractMusicOn.Checked) { if (line == "[J'J'J~]" || line == "[J'J'J']") line = "[ ♪ ♪ ♪ ]"; line = line.Replace(" J' ", " ♪ "); if (line.StartsWith("J'")) { line = "♪ " + line.Remove(0, 2).TrimStart(); } if (line.StartsWith("<i>J'")) { line = "<i>♪ " + line.Remove(0, 5).TrimStart(); } if (line.StartsWith("[J'")) { line = "[♪ " + line.Remove(0, 3).TrimStart(); } if (line.StartsWith("<i>[J'")) { line = "<i>[♪ " + line.Remove(0, 6).TrimStart(); } if (line.EndsWith("J'")) { line = line.Remove(line.Length - 2, 2).TrimEnd() + " ♪"; } if (line.EndsWith("J'</i>")) { line = line.Remove(line.Length - 6, 6).TrimEnd() + " ♪</i>"; } if (line.Contains(Environment.NewLine + "J'")) { line = line.Replace(Environment.NewLine + "J'", Environment.NewLine + "♪ "); line = line.Replace(" ", " "); } if (line.Contains("J'" + Environment.NewLine)) { line = line.Replace("J'" + Environment.NewLine, " ♪" + Environment.NewLine); line = line.Replace(" ", " "); } } if (wordsNotFound > 0 || correctWords == 0 || textWithOutFixes != null && textWithOutFixes.ToString().Replace("~", string.Empty).Trim().Length < 2) { _ocrFixEngine.AutoGuessesUsed.Clear(); _ocrFixEngine.UnknownWordsFound.Clear(); if (_modiEnabled && checkBoxUseModiInTesseractForUnknownWords.Checked) { // which is best - modi or tesseract - we find out here string modiText = CallModi(index); if (modiText.Length == 0) modiText = CallModi(index); // retry... strange MODI if (modiText.Length == 0) modiText = CallModi(index); // retry... strange MODI if (modiText.Length > 1 && !modiText.Contains("CD") && (!modiText.Contains("0") || line.Contains("0")) && (!modiText.Contains("2") || line.Contains("2")) && (!modiText.Contains("3") || line.Contains("4")) && (!modiText.Contains("5") || line.Contains("5")) && (!modiText.Contains("9") || line.Contains("9")) && (!modiText.Contains("•") || line.Contains("•")) && (!modiText.Contains(")") || line.Contains(")")) && Utilities.CountTagInText(modiText, "(") < 2 && Utilities.CountTagInText(modiText, ")") < 2 && Utilities.CountTagInText(modiText, Environment.NewLine) < 3) { int modiWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(modiText, out correctWords); //if (modiWordsNotFound > 0) { string modiTextOcrFixed = modiText; if (checkBoxAutoFixCommonErrors.Checked) modiTextOcrFixed = _ocrFixEngine.FixOcrErrors(modiText, index, _lastLine, false, checkBoxGuessUnknownWords.Checked); int modiOcrCorrectedWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(modiTextOcrFixed, out correctWords); if (modiOcrCorrectedWordsNotFound <= modiWordsNotFound) modiText = modiTextOcrFixed; } if (modiWordsNotFound < wordsNotFound || (textWithOutFixes.Length == 1 && modiWordsNotFound == 0)) line = modiText; // use the modi ocr'ed text else if (wordsNotFound == modiWordsNotFound && modiText.EndsWith("!") && (line.EndsWith("l") || line.EndsWith("fl"))) line = modiText; } // take the best option - before ocr fixing, which we do again to save suggestions and prompt for user input line = _ocrFixEngine.FixUnknownWordsViaGuessOrPrompt(out wordsNotFound, line, index, bitmap, checkBoxAutoFixCommonErrors.Checked, checkBoxPromptForUnknownWords.Checked, true, checkBoxGuessUnknownWords.Checked); } else { // fix some error manually (modi not available) line = _ocrFixEngine.FixUnknownWordsViaGuessOrPrompt(out wordsNotFound, line, index, bitmap, checkBoxAutoFixCommonErrors.Checked, checkBoxPromptForUnknownWords.Checked, true, checkBoxGuessUnknownWords.Checked); } } if (_ocrFixEngine.Abort) { ButtonStopClick(null, null); _ocrFixEngine.Abort = false; return string.Empty; } //check tesseract... find some otherway to do this... //string tmp = Utilities.RemoveHtmlTags(line).Trim(); //if (!tmp.Trim().EndsWith("...")) //{ // tmp = tmp.TrimEnd('.').TrimEnd(); // if (tmp.Length > 2 && Utilities.LowercaseLetters.Contains(tmp.Substring(tmp.Length - 1, 1))) // { // if (_nocrChars == null) // _nocrChars = LoadNOcrForTesseract("Nikse.SubtitleEdit.Resources.nOCR_TesseractHelper.xml.zip"); // string text = Utilities.RemoveHtmlTags(NocrFastCheck(bitmap).TrimEnd()); // string post = string.Empty; // if (line.EndsWith("</i>")) // { // post = "</i>"; // line = line.Remove(line.Length - 4, 4).Trim(); // } // if (text.EndsWith(".")) // { // line = line.TrimEnd('.').Trim(); // while (text.EndsWith(".") || text.EndsWith(" ")) // { // line += text.Substring(text.Length - 1).Trim(); // text = text.Remove(text.Length - 1, 1); // } // } // else if (text.EndsWith("l") && text.EndsWith("!") && !text.EndsWith("l!")) // { // line = line.Remove(line.Length - 1, 1) + "!"; // } // line += post; // } //} // 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(index, Color.Red); if (wordsNotFound == 2) subtitleListView1.SetBackgroundColor(index, Color.Orange); else if (wordsNotFound == 1 || line.Length == 1 || line.Contains("_") || HasSingleLetters(line)) subtitleListView1.SetBackgroundColor(index, Color.Yellow); else if (line.Trim().Length == 0) subtitleListView1.SetBackgroundColor(index, Color.Orange); else subtitleListView1.SetBackgroundColor(index, Color.LightGreen); } else { // no dictionary :( if (checkBoxAutoFixCommonErrors.Checked) line = _ocrFixEngine.FixOcrErrors(line, index, _lastLine, true, checkBoxGuessUnknownWords.Checked); if (badWords >= numberOfWords) subtitleListView1.SetBackgroundColor(index, Color.Red); else if (badWords >= numberOfWords / 2) subtitleListView1.SetBackgroundColor(index, Color.Orange); else if (badWords > 0 || line.Contains("_") || HasSingleLetters(line)) subtitleListView1.SetBackgroundColor(index, Color.Yellow); else if (line.Replace("<i>", string.Empty).Replace("</i>", string.Empty).Trim().Length == 0) subtitleListView1.SetBackgroundColor(index, Color.Orange); else subtitleListView1.SetBackgroundColor(index, Color.LightGreen); } if (textWithOutFixes.ToString().Trim() != line.Trim()) { _tesseractOcrAutoFixes++; labelFixesMade.Text = string.Format(" - {0}", _tesseractOcrAutoFixes); LogOcrFix(index, textWithOutFixes.ToString(), line); } if (_vobSubMergedPackist != null) bitmap.Dispose(); return line; }
public Bitmap GetSubtitleBitmap(int index) { Bitmap returnBmp = null; Color background; Color pattern; Color emphasis1; Color emphasis2; if (_mp4List != null) { if (checkBoxCustomFourColors.Checked) { GetCustomColors(out background, out pattern, out emphasis1, out emphasis2); returnBmp = _mp4List[index].Picture.GetBitmap(null, background, pattern, emphasis1, emphasis2, true); if (checkBoxAutoTransparentBackground.Checked) returnBmp.MakeTransparent(); } else { returnBmp = _mp4List[index].Picture.GetBitmap(null, Color.Transparent, Color.Black, Color.White, Color.Black, false); if (checkBoxAutoTransparentBackground.Checked) returnBmp.MakeTransparent(); } } else if (_spList != null) { if (checkBoxCustomFourColors.Checked) { GetCustomColors(out background, out pattern, out emphasis1, out emphasis2); returnBmp = _spList[index].Picture.GetBitmap(null, background, pattern, emphasis1, emphasis2, true); if (checkBoxAutoTransparentBackground.Checked) returnBmp.MakeTransparent(); } else { returnBmp = _spList[index].Picture.GetBitmap(null, Color.Transparent, Color.Black, Color.White, Color.Black, false); if (checkBoxAutoTransparentBackground.Checked) returnBmp.MakeTransparent(); } } else if (_bdnXmlSubtitle != null) { if (index >= 0 && index < _bdnXmlSubtitle.Paragraphs.Count) { string[] fileNames = _bdnXmlSubtitle.Paragraphs[index].Text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); var bitmaps = new List<Bitmap>(); int maxWidth = 0; int totalHeight = 0; foreach (string fn in fileNames) { string fullFileName = Path.Combine(Path.GetDirectoryName(_bdnFileName), fn); if (File.Exists(fullFileName)) { try { var temp = new Bitmap(fullFileName); if (temp.Width > maxWidth) maxWidth = temp.Width; totalHeight += temp.Height; bitmaps.Add(temp); } catch { return null; } } } Bitmap b = null; if (bitmaps.Count > 1) { var merged = new Bitmap(maxWidth, totalHeight + 7 * bitmaps.Count); int y = 0; for (int k = 0; k < bitmaps.Count; k++) { Bitmap part = bitmaps[k]; if (checkBoxAutoTransparentBackground.Checked) part.MakeTransparent(); using (var g = Graphics.FromImage(merged)) g.DrawImage(part, 0, y); y += part.Height + 7; part.Dispose(); } b = merged; } else if (bitmaps.Count == 1) { b = bitmaps[0]; } if (b != null) { if (_isSon && checkBoxCustomFourColors.Checked) { GetCustomColors(out background, out pattern, out emphasis1, out emphasis2); FastBitmap fbmp = new FastBitmap(b); fbmp.LockImage(); for (int x = 0; x < fbmp.Width; x++) { for (int y = 0; y < fbmp.Height; y++) { Color c = fbmp.GetPixel(x, y); if (c.R == Color.Red.R && c.G == Color.Red.G && c.B == Color.Red.B) // normally anti-alias fbmp.SetPixel(x, y, emphasis2); else if (c.R == Color.Blue.R && c.G == Color.Blue.G && c.B == Color.Blue.B) // normally text? fbmp.SetPixel(x, y, pattern); else if (c.R == Color.White.R && c.G == Color.White.G && c.B == Color.White.B) // normally background fbmp.SetPixel(x, y, background); else if (c.R == Color.Black.R && c.G == Color.Black.G && c.B == Color.Black.B) // outline/border fbmp.SetPixel(x, y, emphasis1); else fbmp.SetPixel(x, y, c); } } fbmp.UnlockImage(); } if (checkBoxAutoTransparentBackground.Checked) b.MakeTransparent(); returnBmp = b; } } } else if (_xSubList != null) { if (checkBoxCustomFourColors.Checked) { GetCustomColors(out background, out pattern, out emphasis1, out emphasis2); returnBmp = _xSubList[index].GetImage(background, pattern, emphasis1, emphasis2); } else { returnBmp = _xSubList[index].GetImage(); } } else if (_dvbSubtitles != null) { var dvbBmp = _dvbSubtitles[index].GetActiveImage(); var nDvbBmp = new NikseBitmap(dvbBmp); nDvbBmp.CropTopTransparent(2); nDvbBmp.CropTransparentSidesAndBottom(2, true); if (checkBoxTransportStreamGetColorAndSplit.Checked) _dvbSubColor = nDvbBmp.GetBrightestColor(); if (checkBoxAutoTransparentBackground.Checked) nDvbBmp.MakeBackgroundTransparent((int)numericUpDownAutoTransparentAlphaMax.Value); if (checkBoxTransportStreamGrayscale.Checked) nDvbBmp.GrayScale(); dvbBmp.Dispose(); returnBmp = nDvbBmp.GetBitmap(); } else if (_bluRaySubtitlesOriginal != null) { returnBmp = _bluRaySubtitles[index].GetBitmap(); } else if (checkBoxCustomFourColors.Checked) { GetCustomColors(out background, out pattern, out emphasis1, out emphasis2); returnBmp = _vobSubMergedPackist[index].SubPicture.GetBitmap(null, background, pattern, emphasis1, emphasis2, true); if (checkBoxAutoTransparentBackground.Checked) returnBmp.MakeTransparent(); } else { returnBmp = _vobSubMergedPackist[index].SubPicture.GetBitmap(_palette, Color.Transparent, Color.Black, Color.White, Color.Black, false); if (checkBoxAutoTransparentBackground.Checked) returnBmp.MakeTransparent(); } if (_binaryOcrDb == null && _nOcrDb == null) return returnBmp; var n = new NikseBitmap(returnBmp); n.MakeTwoColor(210, 280); returnBmp.Dispose(); return n.GetBitmap(); }
public Bitmap ToOldBitmap() { NikseBitmap nbmp = new NikseBitmap(Width, Height); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { nbmp.SetPixel(x, y, this.GetPixel(x, y)); } } return nbmp.GetBitmap(); }
private Bitmap GenerateImageFromTextWithStyle(string text) { const bool subtitleFontBold = false; bool subtitleAlignLeft = comboBoxHAlign.SelectedIndex == 0; // remove styles for display text (except italic) text = RemoveSubStationAlphaFormatting(text); text = text.Replace("<b>", string.Empty); text = text.Replace("</b>", string.Empty); text = text.Replace("<B>", string.Empty); text = text.Replace("</B>", string.Empty); text = text.Replace("<u>", string.Empty); text = text.Replace("</u>", string.Empty); text = text.Replace("<U>", string.Empty); text = text.Replace("</U>", string.Empty); Font font; try { var fontStyle = FontStyle.Regular; 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 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; bool italicFromStart = false; int newLinePathPoint = -1; Color c = _subtitleColor; var colorStack = new Stack<Color>(); var lastText = new StringBuilder(); while (i < text.Length) { if (text.Substring(i).ToLower().StartsWith("<font ")) { float addLeft = 0; int oldPathPointIndex = path.PointCount; if (oldPathPointIndex < 0) oldPathPointIndex = 0; if (sb.Length > 0) { TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); } if (path.PointCount > 0) { PointF[] list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!! for (int k = oldPathPointIndex; k < list.Length; k++) { if (list[k].X > addLeft) addLeft = list[k].X; } } if (addLeft == 0) addLeft = left + 2; left = addLeft; if (_borderWidth > 0) g.DrawPath(new Pen(_borderColor, _borderWidth), path); g.FillPath(new SolidBrush(c), path); path.Reset(); path = new GraphicsPath(); sb = new StringBuilder(); int endIndex = text.Substring(i).IndexOf('>'); if (endIndex == -1) { i += 9999; } else { string fontContent = text.Substring(i, endIndex); if (fontContent.Contains(" color=")) { string[] arr = fontContent.Substring(fontContent.IndexOf(" color=") + 7).Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string fontColor = arr[0].Trim('\'').Trim('"').Trim('\''); try { colorStack.Push(c); // save old color if (fontColor.StartsWith("rgb(")) { arr = fontColor.Remove(0, 4).TrimEnd(')').Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); c = Color.FromArgb(int.Parse(arr[0]), int.Parse(arr[1]), int.Parse(arr[2])); } else { c = ColorTranslator.FromHtml(fontColor); } } catch { c = _subtitleColor; } } } i += endIndex; } } else if (text.Substring(i).ToLower().StartsWith("</font>")) { if (text.Substring(i).ToLower().Replace("</font>", string.Empty).Length > 0) { if (lastText.EndsWith(' ') && !sb.StartsWith(' ')) { string t = sb.ToString(); sb.Clear(); sb.Append(' '); sb.Append(t); } float addLeft = 0; int oldPathPointIndex = path.PointCount - 1; if (oldPathPointIndex < 0) oldPathPointIndex = 0; if (sb.Length > 0) { TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); } if (path.PointCount > 0) { PointF[] list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!! for (int k = oldPathPointIndex; k < list.Length; k++) { if (list[k].X > addLeft) addLeft = list[k].X; } } if (addLeft == 0) addLeft = left + 2; left = addLeft; if (_borderWidth > 0) g.DrawPath(new Pen(_borderColor, _borderWidth), path); g.FillPath(new SolidBrush(c), path); path.Reset(); //path = new GraphicsPath(); sb = new StringBuilder(); if (colorStack.Count > 0) c = colorStack.Pop(); } i += 6; } else if (text.Substring(i).ToLower().StartsWith("<i>")) { italicFromStart = i == 0; if (sb.Length > 0) { TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); } isItalic = true; i += 2; } else if (text.Substring(i).ToLower().StartsWith("</i>") && isItalic) { if (lastText.EndsWith(' ') && !sb.StartsWith(' ')) { string t = sb.ToString(); sb.Clear(); sb.Append(' '); sb.Append(t); } TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); isItalic = false; i += 3; } else 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; } if (isItalic) italicFromStart = true; } 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); sf.Dispose(); 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(); }
private static Bitmap GenerateImageFromTextWithStyleInner(MakeBitmapParameter parameter) { string text = parameter.P.Text; text = RemoveSubStationAlphaFormatting(text); text = text.Replace("<I>", "<i>"); text = text.Replace("</I>", "</i>"); text = Utilities.FixInvalidItalicTags(text); text = text.Replace("<B>", "<b>"); text = text.Replace("</B>", "</b>"); // no support for underline text = text.Replace("<u>", string.Empty); text = text.Replace("</u>", string.Empty); text = text.Replace("<U>", string.Empty); text = text.Replace("</U>", string.Empty); var bmp = new Bitmap(1, 1); var g = Graphics.FromImage(bmp); var fontSize = g.DpiY * parameter.SubtitleFontSize / 72; Font font = SetFont(parameter, parameter.SubtitleFontSize); var lineHeight = parameter.LineHeight; // (textSize.Height * 0.64f); var textSize = g.MeasureString(Utilities.RemoveHtmlTags(text), font); g.Dispose(); bmp.Dispose(); int sizeX = (int)(textSize.Width * 1.8) + 150; int sizeY = (int)(textSize.Height * 0.9) + 50; if (sizeX < 1) sizeX = 1; if (sizeY < 1) sizeY = 1; bmp = new Bitmap(sizeX, sizeY); if (parameter.BackgroundColor != Color.Transparent) { NikseBitmap nbmpTemp = new NikseBitmap(bmp); nbmpTemp.Fill(parameter.BackgroundColor); var temp = nbmpTemp.GetBitmap(); bmp.Dispose(); bmp = temp; // g.FillRectangle(new SolidBrush(parameter.BackgroundColor), 0, 0, bmp.Width, bmp.Height); } g = Graphics.FromImage(bmp); // align lines with gjpqy, a bit lower var lines = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); int baseLinePadding = 13; if (parameter.SubtitleFontSize < 30) baseLinePadding = 12; if (parameter.SubtitleFontSize < 25) baseLinePadding = 9; if (lines.Length > 0) { if (lines[lines.Length - 1].Contains("g") || lines[lines.Length - 1].Contains("j") || lines[lines.Length - 1].Contains("p") || lines[lines.Length - 1].Contains("q") || lines[lines.Length - 1].Contains("y") || lines[lines.Length - 1].Contains(",")) { string textNoBelow = lines[lines.Length - 1].Replace("g", "a").Replace("j", "a").Replace("p", "a").Replace("q", "a").Replace("y", "a").Replace(",", "a"); baseLinePadding -= (int)Math.Round((TextDraw.MeasureTextHeight(font, lines[lines.Length - 1], parameter.SubtitleFontBold) - TextDraw.MeasureTextHeight(font, textNoBelow, parameter.SubtitleFontBold))); } else { baseLinePadding += 1; } if (baseLinePadding < 0) baseLinePadding = 0; } //TODO: Better baseline - test http://bobpowell.net/formattingtext.aspx //float baselineOffset=font.SizeInPoints/font.FontFamily.GetEmHeight(font.Style)*font.FontFamily.GetCellAscent(font.Style); //float baselineOffsetPixels = g.DpiY/72f*baselineOffset; //baseLinePadding = (int)Math.Round(baselineOffsetPixels); var lefts = new List<float>(); if (text.ToLower().Contains("<font") || text.ToLower().Contains("<i>")) { foreach (string line in text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) { string lineNoHtml = Utilities.RemoveHtmlFontTag(line.Replace("<i>", string.Empty).Replace("</i>", string.Empty)); if (parameter.AlignLeft) lefts.Add(5); else if (parameter.AlignRight) lefts.Add(bmp.Width - CalcWidthViaDraw(lineNoHtml, parameter) - 15); // calculate via drawing+crop else lefts.Add((bmp.Width - CalcWidthViaDraw(lineNoHtml, parameter) + 5) / 2); // calculate via drawing+crop } } else { foreach (string line in Utilities.RemoveHtmlFontTag(text.Replace("<i>", string.Empty).Replace("</i>", string.Empty)).Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) { if (parameter.AlignLeft) lefts.Add(5); else if (parameter.AlignRight) lefts.Add(bmp.Width - (TextDraw.MeasureTextWidth(font, line, parameter.SubtitleFontBold) + 15)); else lefts.Add((bmp.Width - TextDraw.MeasureTextWidth(font, line, parameter.SubtitleFontBold) + 15) / 2); } } g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; var sf = new StringFormat(); sf.Alignment = StringAlignment.Near; sf.LineAlignment = StringAlignment.Near;// draw the text to a path if (parameter.SimpleRendering) { if (text.StartsWith("<font ") && Utilities.CountTagInText(text, "<font") == 1) { parameter.SubtitleColor = Utilities.GetColorFromFontString(text, parameter.SubtitleColor); } text = Utilities.RemoveHtmlTags(text, true); //TODO: Perhaps check single color... var brush = new SolidBrush(parameter.BorderColor); int x = 3; int y = 3; sf.Alignment = StringAlignment.Near; if (parameter.AlignLeft) { sf.Alignment = StringAlignment.Near; } else if (parameter.AlignRight) { sf.Alignment = StringAlignment.Far; x = parameter.ScreenWidth - 5; } else { sf.Alignment = StringAlignment.Center; x = parameter.ScreenWidth / 2; } bmp = new Bitmap(parameter.ScreenWidth, sizeY); Graphics surface = Graphics.FromImage(bmp); surface.CompositingQuality = CompositingQuality.HighSpeed; surface.InterpolationMode = InterpolationMode.Default; surface.SmoothingMode = SmoothingMode.HighSpeed; surface.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; for (int j = 0; j < parameter.BorderWidth; j++) { surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 0 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y + 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 0 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y + 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 0 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y + 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y - 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y - 0 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y + 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y - 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y - 0 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y + 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y - 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y - 0 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y + 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y - 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y - 0 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y + 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y - 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y - 0 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y + 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y - 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y - 0 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y + 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 0 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y + 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 0 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y + 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 0 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y + 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 0 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y + 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 0 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y + 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 0 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y + 1 + j }, sf); surface.DrawString(text, font, brush, new PointF { X = x, Y = y - 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x, Y = y - 0 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x, Y = y + 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + 1, Y = y - 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + 1, Y = y - 0 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x + 1, Y = y + 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - 1, Y = y - 1 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - 1, Y = y - 0 - j }, sf); surface.DrawString(text, font, brush, new PointF { X = x - 1, Y = y + 1 - j }, sf); } brush.Dispose(); brush = new SolidBrush(parameter.SubtitleColor); surface.CompositingQuality = CompositingQuality.HighQuality; surface.SmoothingMode = SmoothingMode.HighQuality; surface.InterpolationMode = InterpolationMode.HighQualityBicubic; surface.DrawString(text, font, brush, new PointF { X = x, Y = y }, sf); surface.Dispose(); brush.Dispose(); } else { var path = new GraphicsPath(); var sb = new StringBuilder(); int i = 0; bool isItalic = false; bool isBold = parameter.SubtitleFontBold; 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 = parameter.SubtitleColor; var colorStack = new Stack<Color>(); var lastText = new StringBuilder(); while (i < text.Length) { if (text.Substring(i).ToLower().StartsWith("<font ")) { float addLeft = 0; int oldPathPointIndex = path.PointCount; if (oldPathPointIndex < 0) oldPathPointIndex = 0; if (sb.Length > 0) { lastText.Append(sb); TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); } if (path.PointCount > 0) { PointF[] list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!! for (int k = oldPathPointIndex; k < list.Length; k++) { if (list[k].X > addLeft) addLeft = list[k].X; } } if (path.PointCount == 0) addLeft = left; else if (addLeft < 0.01) addLeft = left + 2; left = addLeft; DrawShadowAndPAth(parameter, g, path); var p2 = new SolidBrush(c); g.FillPath(p2, path); p2.Dispose(); path.Reset(); path = new GraphicsPath(); sb = new StringBuilder(); int endIndex = text.Substring(i).IndexOf(">", StringComparison.Ordinal); if (endIndex == -1) { i += 9999; } else { string fontContent = text.Substring(i, endIndex); if (fontContent.Contains(" color=")) { string[] arr = fontContent.Substring(fontContent.IndexOf(" color=", StringComparison.Ordinal) + 7).Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string fontColor = arr[0].Trim('\'').Trim('"').Trim('\''); try { colorStack.Push(c); // save old color if (fontColor.StartsWith("rgb(")) { arr = fontColor.Remove(0, 4).TrimEnd(')').Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); c = Color.FromArgb(int.Parse(arr[0]), int.Parse(arr[1]), int.Parse(arr[2])); } else { c = ColorTranslator.FromHtml(fontColor); } } catch { c = parameter.SubtitleColor; } } } i += endIndex; } } else if (text.Substring(i).ToLower().StartsWith("</font>")) { if (text.Substring(i).ToLower().Replace("</font>", string.Empty).Length > 0) { if (lastText.ToString().EndsWith(" ") && !sb.ToString().StartsWith(" ")) { string t = sb.ToString(); sb = new StringBuilder(); sb.Append(" " + t); } float addLeft = 0; int oldPathPointIndex = path.PointCount - 1; if (oldPathPointIndex < 0) oldPathPointIndex = 0; if (sb.Length > 0) { if (lastText.Length > 0 && left > 2) left -= 1.5f; lastText.Append(sb); TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); } if (path.PointCount > 0) { PointF[] list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!! for (int k = oldPathPointIndex; k < list.Length; k++) { if (list[k].X > addLeft) addLeft = list[k].X; } } if (addLeft < 0.01) addLeft = left + 2; left = addLeft; DrawShadowAndPAth(parameter, g, path); g.FillPath(new SolidBrush(c), path); path.Reset(); sb = new StringBuilder(); if (colorStack.Count > 0) c = colorStack.Pop(); if (left >= 3) left -= 2.5f; } i += 6; } else if (text.Substring(i).ToLower().StartsWith("<i>")) { if (sb.ToString().Trim().Length > 0) { lastText.Append(sb); TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); } isItalic = true; i += 2; } else if (text.Substring(i).ToLower().StartsWith("</i>") && isItalic) { if (lastText.ToString().EndsWith(" ") && !sb.ToString().StartsWith(" ")) { string t = sb.ToString(); sb = new StringBuilder(); sb.Append(" " + t); } lastText.Append(sb); TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); isItalic = false; i += 3; } else if (text.Substring(i).ToLower().StartsWith("<b>")) { if (sb.ToString().Trim().Length > 0) { lastText.Append(sb); TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); } isBold = true; i += 2; } else if (text.Substring(i).ToLower().StartsWith("</b>") && isBold) { if (lastText.ToString().EndsWith(" ") && !sb.ToString().StartsWith(" ")) { string t = sb.ToString(); sb = new StringBuilder(); sb.Append(" " + t); } lastText.Append(sb); TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); isBold = false; i += 3; } else if (text.Substring(i).StartsWith(Environment.NewLine)) { lastText.Append(sb); TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, 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, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); DrawShadowAndPAth(parameter, g, path); g.FillPath(new SolidBrush(c), path); } g.Dispose(); sf.Dispose(); var nbmp = new NikseBitmap(bmp); if (parameter.BackgroundColor == Color.Transparent) { nbmp.CropTransparentSidesAndBottom(baseLinePadding, true); nbmp.CropTransparentSidesAndBottom(2, false); } else { nbmp.CropSidesAndBottom(4, parameter.BackgroundColor, true); nbmp.CropTop(4, parameter.BackgroundColor); } if (nbmp.Width > parameter.ScreenWidth) { parameter.Error = "#" + parameter.P.Number.ToString(CultureInfo.InvariantCulture) + ": " + nbmp.Width.ToString(CultureInfo.InvariantCulture) + " > " + parameter.ScreenWidth.ToString(CultureInfo.InvariantCulture); } if (parameter.Type3D == 1) // Half-side-by-side 3D { Bitmap singleBmp = nbmp.GetBitmap(); Bitmap singleHalfBmp = ScaleToHalfWidth(singleBmp); singleBmp.Dispose(); Bitmap sideBySideBmp = new Bitmap(parameter.ScreenWidth, singleHalfBmp.Height); int singleWidth = parameter.ScreenWidth / 2; int singleLeftMargin = (singleWidth - singleHalfBmp.Width) / 2; using (Graphics gSideBySide = Graphics.FromImage(sideBySideBmp)) { gSideBySide.DrawImage(singleHalfBmp, singleLeftMargin + parameter.Depth3D, 0); gSideBySide.DrawImage(singleHalfBmp, singleWidth + singleLeftMargin - parameter.Depth3D, 0); } nbmp = new NikseBitmap(sideBySideBmp); if (parameter.BackgroundColor == Color.Transparent) nbmp.CropTransparentSidesAndBottom(2, true); else nbmp.CropSidesAndBottom(4, parameter.BackgroundColor, true); } else if (parameter.Type3D == 2) // Half-Top/Bottom 3D { nbmp = Make3DTopBottom(parameter, nbmp); } return nbmp.GetBitmap(); }
private Bitmap GenerateImageFromTextWithStyle(Paragraph p, out MakeBitmapParameter mbp) { mbp = new MakeBitmapParameter(); mbp.P = p; if (_vobSubOcr != null) { var index = _subtitle.GetIndex(p); if (index >= 0) return _vobSubOcr.GetSubtitleBitmap(index); } mbp.AlignLeft = comboBoxHAlign.SelectedIndex == 0; mbp.AlignRight = comboBoxHAlign.SelectedIndex == 2; mbp.SimpleRendering = checkBoxSimpleRender.Checked; mbp.BorderWidth = _borderWidth; mbp.BorderColor = _borderColor; mbp.SubtitleFontName = _subtitleFontName; mbp.SubtitleColor = _subtitleColor; mbp.SubtitleFontSize = _subtitleFontSize; mbp.SubtitleFontBold = _subtitleFontBold; mbp.LineHeight = (int) numericUpDownLineSpacing.Value; if (_format.HasStyleSupport && !string.IsNullOrEmpty(p.Extra)) { if (_format.GetType() == typeof(SubStationAlpha)) { var style = AdvancedSubStationAlpha.GetSsaStyle(p.Extra, _subtitle.Header); mbp.SubtitleColor = style.Primary; mbp.SubtitleFontBold = style.Bold; mbp.SubtitleFontSize = style.FontSize; if (style.BorderStyle == "3") { mbp.BackgroundColor = style.Background; } } else if (_format.GetType() == typeof(AdvancedSubStationAlpha)) { var style = AdvancedSubStationAlpha.GetSsaStyle(p.Extra, _subtitle.Header); mbp.SubtitleColor = style.Primary; mbp.SubtitleFontBold = style.Bold; mbp.SubtitleFontSize = style.FontSize; if (style.BorderStyle == "3") { mbp.BackgroundColor = style.Outline; } } } if (comboBoxBorderWidth.SelectedItem.ToString() == Configuration.Settings.Language.ExportPngXml.BorderStyleBoxForEachLine) { _borderWidth = 0; mbp.BackgroundColor = panelBorderColor.BackColor; mbp.BoxSingleLine = true; } else if (comboBoxBorderWidth.SelectedItem.ToString() == Configuration.Settings.Language.ExportPngXml.BorderStyleOneBox) { _borderWidth = 0; mbp.BackgroundColor = panelBorderColor.BackColor; } int width = 0; int height = 0; GetResolution(ref width, ref height); mbp.ScreenWidth = width; mbp.ScreenHeight = height; mbp.Type3D = comboBox3D.SelectedIndex; mbp.Depth3D = (int)numericUpDownDepth3D.Value; mbp.BottomMargin = comboBoxBottomMargin.SelectedIndex; mbp.ShadowWidth = comboBoxShadowWidth.SelectedIndex; mbp.ShadowAlpha = (int)numericUpDownShadowTransparency.Value; mbp.ShadowColor = panelShadowColor.BackColor; mbp.LineHeight = (int)numericUpDownLineSpacing.Value; if (_exportType == "VOBSUB" || _exportType == "STL" || _exportType == "SPUMUX") { mbp.LineJoinRound = true; } var bmp = GenerateImageFromTextWithStyle(mbp); if (_exportType == "VOBSUB" || _exportType == "STL" || _exportType == "SPUMUX") { var nbmp = new NikseBitmap(bmp); nbmp.ConverToFourColors(Color.Transparent, _subtitleColor, _borderColor, !checkBoxTransAntiAliase.Checked); var temp = nbmp.GetBitmap(); bmp.Dispose(); return temp; } return bmp; }
private static NikseBitmap Make3DTopBottom(MakeBitmapParameter parameter, NikseBitmap nbmp) { Bitmap singleBmp = nbmp.GetBitmap(); Bitmap singleHalfBmp = ScaleToHalfHeight(singleBmp); singleBmp.Dispose(); Bitmap topBottomBmp = new Bitmap(parameter.ScreenWidth, parameter.ScreenHeight - parameter.BottomMargin); int singleHeight = parameter.ScreenHeight / 2; int leftM = (parameter.ScreenWidth / 2) - (singleHalfBmp.Width / 2); using (Graphics gTopBottom = Graphics.FromImage(topBottomBmp)) { gTopBottom.DrawImage(singleHalfBmp, leftM + parameter.Depth3D, singleHeight - singleHalfBmp.Height - parameter.BottomMargin); gTopBottom.DrawImage(singleHalfBmp, leftM - parameter.Depth3D, parameter.ScreenHeight - parameter.BottomMargin - singleHalfBmp.Height); } nbmp = new NikseBitmap(topBottomBmp); if (parameter.BackgroundColor == Color.Transparent) { nbmp.CropTop(2, Color.Transparent); nbmp.CropTransparentSidesAndBottom(2, false); } else { nbmp.CropTop(4, parameter.BackgroundColor); nbmp.CropSidesAndBottom(4, parameter.BackgroundColor, false); } return nbmp; }
static void NOcrThreadDoWork(object sender, DoWorkEventArgs e) { var p = (NOcrThreadParameter)e.Argument; e.Result = p; var nbmpInput = new NikseBitmap(p.Picture); nbmpInput.ReplaceNonWhiteWithTransparent(); var matches = new List<CompareMatch>(); int minLineHeight = p.NOcrLastLowercaseHeight; if (minLineHeight < 10) minLineHeight = 22; int maxLineHeight = p.NOcrLastUppercaseHeight; if (maxLineHeight < 10) minLineHeight = 80; List<ImageSplitterItem> lines = NikseBitmapImageSplitter.SplitVertical(nbmpInput, minLineHeight); List<ImageSplitterItem> list = NikseBitmapImageSplitter.SplitBitmapToLetters(lines, p.NumberOfPixelsIsSpace, p.RightToLeft, Configuration.Settings.VobSubOcr.TopToBottom); foreach (ImageSplitterItem item in list) { if (item.NikseBitmap != null) { var nbmp = item.NikseBitmap; nbmp.ReplaceNonWhiteWithTransparent(); item.Y += nbmp.CropTopTransparent(0); nbmp.CropTransparentSidesAndBottom(0, true); nbmp.ReplaceTransparentWith(Color.Black); } } int index = 0; while (index < list.Count) { ImageSplitterItem item = list[index]; if (item.NikseBitmap == null) { matches.Add(new CompareMatch(item.SpecialCharacter, false, 0, null)); } else { CompareMatch match = GetNOcrCompareMatch(item, nbmpInput.GetBitmap(), p); if (match == null) { p.Result = string.Empty; return; } else // found image match { matches.Add(new CompareMatch(match.Text, match.Italic, 0, null)); if (match.ExpandCount > 0) index += match.ExpandCount - 1; } } index++; } p.Result = GetStringWithItalicTags(matches); }
static string NocrThreadDoItalicWork(NOcrThreadParameter p) { var unItalicedBmp = UnItalic(p.Picture, p.UnItalicFactor); var nbmp = new NikseBitmap(unItalicedBmp); nbmp.ReplaceNonWhiteWithTransparent(); Bitmap bitmap = nbmp.GetBitmap(); unItalicedBmp.Dispose(); var matches = new List<CompareMatch>(); int minLineHeight = p.NOcrLastLowercaseHeight; if (minLineHeight < 10) minLineHeight = 22; int maxLineHeight = p.NOcrLastUppercaseHeight; if (maxLineHeight < 10) minLineHeight = 80; List<ImageSplitterItem> lines = NikseBitmapImageSplitter.SplitVertical(nbmp, minLineHeight); List<ImageSplitterItem> list = NikseBitmapImageSplitter.SplitBitmapToLetters(lines, p.NumberOfPixelsIsSpace, p.RightToLeft, Configuration.Settings.VobSubOcr.TopToBottom); foreach (ImageSplitterItem item in list) { if (item.NikseBitmap != null) { item.NikseBitmap.ReplaceNonWhiteWithTransparent(); item.Y += item.NikseBitmap.CropTopTransparent(0); item.NikseBitmap.CropTransparentSidesAndBottom(0, true); item.NikseBitmap.ReplaceTransparentWith(Color.Black); } } int index = 0; while (index < list.Count) { ImageSplitterItem item = list[index]; if (item.NikseBitmap == null) { matches.Add(new CompareMatch(item.SpecialCharacter, false, 0, null)); } else { bool old = p.AdvancedItalicDetection; p.AdvancedItalicDetection = false; CompareMatch match = GetNOcrCompareMatch(item, bitmap, p); p.AdvancedItalicDetection = old; if (match == null) { return string.Empty; } else // found image match { matches.Add(new CompareMatch(match.Text, match.Italic, 0, null)); if (match.ExpandCount > 0) index += match.ExpandCount - 1; } } index++; } return "<i>" + Utilities.RemoveHtmlTags(GetStringWithItalicTags(matches)) + "</i>"; }
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; }
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(); }
private void listBoxFileNames_SelectedIndexChanged(object sender, EventArgs e) { labelNOcrCharInfo.Text = string.Empty; if (listBoxFileNames.SelectedIndex < 0) return; _nocrChar = listBoxFileNames.Items[listBoxFileNames.SelectedIndex] as NOcrChar; if (_nocrChar == null) { pictureBoxCharacter.Invalidate(); groupBoxCurrentCompareImage.Enabled = false; listBoxLinesForeground.Items.Clear(); listBoxlinesBackground.Items.Clear(); } else { textBoxText.Text = _nocrChar.Text; checkBoxItalic.Checked = _nocrChar.Italic; pictureBoxCharacter.Invalidate(); groupBoxCurrentCompareImage.Enabled = true; labelNOcrCharInfo.Text = string.Format("Size: {0}x{1}, margin top: {2} ", _nocrChar.Width, _nocrChar.Height, _nocrChar.MarginTop); if (pictureBoxCharacter.Image != null) { if (IsMatch()) { groupBoxCurrentCompareImage.BackColor = Color.LightGreen; } else { groupBoxCurrentCompareImage.BackColor = Control.DefaultBackColor; } } _drawLineOn = false; _history = new List<NOcrChar>(); _historyIndex = -1; if (_bitmap == null) { var bitmap = new Bitmap(_nocrChar.Width, _nocrChar.Height); var nbmp = new NikseBitmap(bitmap); nbmp.Fill(Color.White); pictureBoxCharacter.Image = nbmp.GetBitmap(); SizePictureBox(); ShowOcrPoints(); bitmap.Dispose(); } } }