private void RefreshImage() { PreprocessingSettings.InvertColors = checkBoxInvertColors.Checked; PreprocessingSettings.BinaryImageCompareThreshold = (int)numericUpDownThreshold.Value; PreprocessingSettings.ScalingPercent = (int)numericUpDownScaling.Value; pictureBox1.Image?.Dispose(); var n = new NikseBitmap(_source); if (PreprocessingSettings.InvertColors) { n.InvertColors(); } n.MakeTwoColor((int)numericUpDownThreshold.Value, Color.White, Color.Black); if (PreprocessingSettings.ScalingPercent > 100) { var bTemp = n.GetBitmap(); var f = PreprocessingSettings.ScalingPercent / 100.0; var b = ResizeBitmap(bTemp, (int)Math.Round(bTemp.Width * f), (int)Math.Round(bTemp.Height * f)); bTemp.Dispose(); pictureBox1.Image = b; return; } pictureBox1.Image = n.GetBitmap(); }
public static Bitmap ChangeBrightness(Bitmap bitmap, decimal factor) { var n = new NikseBitmap(bitmap); n.ChangeBrightness(factor); return(n.GetBitmap()); }
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 void numericUpDownThreshold_ValueChanged(object sender, EventArgs e) { pictureBox1.Image?.Dispose(); var n = new NikseBitmap(_source); n.MakeTwoColor((int)numericUpDownThreshold.Value); pictureBox1.Image = n.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; if (_nOcrChar.ExpandCount > 0) { labelNOcrCharInfo.Text = string.Format("Size: {0}x{1}, margin top: {2}, expand count: {3}", _nOcrChar.Width, _nOcrChar.Height, _nOcrChar.MarginTop, _nOcrChar.ExpandCount); } else { 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 = 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(); bitmap.Dispose(); } ShowOcrPoints(); } }
private void RefreshImage() { if (_loading) { return; } PreprocessingSettings.InvertColors = checkBoxInvertColors.Checked; PreprocessingSettings.BinaryImageCompareThreshold = (int)numericUpDownThreshold.Value; PreprocessingSettings.ScalingPercent = (int)numericUpDownScaling.Value; PreprocessingSettings.CropTransparentColors = checkBoxCropTransparent.Checked; pictureBox1.Image?.Dispose(); var n = new NikseBitmap(_source); if (PreprocessingSettings.CropTransparentColors) { n.CropSidesAndBottom(2, Color.Transparent, true); n.CropSidesAndBottom(2, Color.FromArgb(0, 0, 0, 0), true); n.CropTop(2, Color.Transparent); n.CropTop(2, Color.FromArgb(0, 0, 0, 0)); } if (PreprocessingSettings.InvertColors) { n.InvertColors(); n.MakeTwoColor((int)numericUpDownThreshold.Value, Color.Black, Color.White); } else { n.MakeTwoColor((int)numericUpDownThreshold.Value, Color.White, Color.Black); } if (PreprocessingSettings.ScalingPercent > 100) { var bTemp = n.GetBitmap(); var f = PreprocessingSettings.ScalingPercent / 100.0; var b = ResizeBitmap(bTemp, (int)Math.Round(bTemp.Width * f), (int)Math.Round(bTemp.Height * f)); bTemp.Dispose(); pictureBox1.Image = b; return; } pictureBox1.Image = n.GetBitmap(); }
internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showShrink, VobSubOcr.CompareMatch bestGuess, List <VobSubOcr.ImageCompareAddition> additions, VobSubOcr vobSubForm) { 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; _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; _nocrChar.Width = _imageWidth; _nocrChar.Height = _imageHeight; GenerateLineSegments(150, false, _nocrChar, new NikseBitmap(pictureBoxCharacter.Image as Bitmap)); ShowOcrPoints(); pictureBoxCharacter.Invalidate(); }
private void RefreshImage() { PreprocessingSettings.BinaryImageCompareThresshold = (int)numericUpDownThreshold.Value; pictureBox1.Image?.Dispose(); var n = new NikseBitmap(_source); n.MakeTwoColor((int)numericUpDownThreshold.Value, Color.White, Color.Black); pictureBox1.Image = n.GetBitmap(); }
private void subtitleListView1_SelectedIndexChanged(object sender, EventArgs e) { if (subtitleListView1.SelectedItems.Count < 1) { timeUpDownStartTime.TimeCode = new TimeCode(); timeUpDownEndTime.TimeCode = new TimeCode(); numericUpDownX.Value = 0; numericUpDownY.Value = 0; pictureBoxMovableImage.Image?.Dispose(); pictureBoxScreen.Image?.Dispose(); return; } var idx = subtitleListView1.SelectedItems[0].Index; if (_bluRaySubtitles != null) { var sub = _bluRaySubtitles[idx]; var extra = _extra[idx]; timeUpDownStartTime.TimeCode = sub.StartTimeCode; timeUpDownEndTime.TimeCode = sub.EndTimeCode; checkBoxIsForced.Checked = extra.Forced; numericUpDownX.Value = extra.X; numericUpDownY.Value = extra.Y; pictureBoxMovableImage.Image?.Dispose(); pictureBoxScreen.Image?.Dispose(); var bmp = extra.Bitmap != null ? (Bitmap)extra.Bitmap.Clone() : sub.GetBitmap(); var nikseBitmap = new NikseBitmap(bmp); nikseBitmap.ReplaceTransparentWith(Color.Black); bmp.Dispose(); bmp = nikseBitmap.GetBitmap(); var screenBmp = new Bitmap((int)numericUpDownScreenWidth.Value, (int)numericUpDownScreenHeight.Value); using (var g = Graphics.FromImage(screenBmp)) { using (var brush = new SolidBrush(Color.Black)) { g.FillRectangle(brush, 0, 0, screenBmp.Width, screenBmp.Height); } //g.DrawImage(bmp, extra.X, extra.Y); } pictureBoxMovableImage.Width = bmp.Width; var widthAspect = pictureBoxScreen.Width / numericUpDownScreenWidth.Value; var heightAspect = pictureBoxScreen.Height / numericUpDownScreenHeight.Value; var scaledBmp = VobSubOcr.ResizeBitmap(bmp, (int)Math.Round(bmp.Width * widthAspect), (int)Math.Round(bmp.Height * heightAspect)); pictureBoxMovableImage.Width = scaledBmp.Width; pictureBoxMovableImage.Height = scaledBmp.Height; pictureBoxMovableImage.SizeMode = PictureBoxSizeMode.StretchImage; pictureBoxMovableImage.Image = scaledBmp; pictureBoxMovableImage.Left = (int)Math.Round(extra.X * widthAspect); pictureBoxMovableImage.Top = (int)Math.Round(extra.Y * heightAspect); pictureBoxScreen.Image = screenBmp; labelCurrentSize.Text = string.Format("Size: {0}x{1}", bmp.Width, bmp.Height); } }
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(); }
internal void Initialize(Bitmap bitmap, int pixelsIsSpace, bool rightToLeft, NOcrDb nOcrDb, VobSubOcr vobSubOcr, double unItalicFactor) { _bitmap = bitmap; var nbmp = new NikseBitmap(bitmap); nbmp.ReplaceNonWhiteWithTransparent(); bitmap = nbmp.GetBitmap(); _bitmap2 = bitmap; _nocrChars = nOcrDb.OcrCharacters; _matchList = new List <VobSubOcr.CompareMatch>(); _vobSubOcr = vobSubOcr; _unItalicFactor = unItalicFactor; 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, _unItalicFactor, 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 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; const 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 var 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++; } }
private void RefreshImage() { if (_loading) { return; } PreprocessingSettings.InvertColors = checkBoxInvertColors.Checked; PreprocessingSettings.YellowToWhite = checkBoxYellowToWhite.Enabled && checkBoxYellowToWhite.Checked; PreprocessingSettings.ColorToWhite = buttonColorToWhite.Enabled ? panelColorToWhite.BackColor : Color.Transparent; PreprocessingSettings.ColorToRemove = buttonColorToRemove.Enabled ? panelColorToRemove.BackColor : Color.Transparent; PreprocessingSettings.CropTransparentColors = checkBoxCropTransparent.Checked; PreprocessingSettings.BinaryImageCompareThreshold = (int)numericUpDownThreshold.Value; pictureBox1.Image?.Dispose(); var n = new NikseBitmap(_source); if (PreprocessingSettings.CropTransparentColors) { n.CropSidesAndBottom(2, Color.Transparent, true); n.CropSidesAndBottom(2, Color.FromArgb(0, 0, 0, 0), true); n.CropTop(2, Color.Transparent); n.CropTop(2, Color.FromArgb(0, 0, 0, 0)); } if (PreprocessingSettings.InvertColors) { n.InvertColors(); } if (PreprocessingSettings.YellowToWhite) { n.ReplaceYellowWithWhite(); } if (panelColorToWhite.BackColor != Color.Transparent) { n.ReplaceColor(panelColorToWhite.BackColor.A, panelColorToWhite.BackColor.R, panelColorToWhite.BackColor.G, panelColorToWhite.BackColor.B, 255, 255, 255, 255); } if (panelColorToRemove.BackColor != Color.Transparent) { n.ReplaceColor(panelColorToRemove.BackColor.A, panelColorToRemove.BackColor.R, panelColorToRemove.BackColor.G, panelColorToRemove.BackColor.B, Color.Transparent.A, Color.Transparent.R, Color.Transparent.G, Color.Transparent.B); } if (_isBinaryImageCompare) { n.MakeTwoColor((int)numericUpDownThreshold.Value); } pictureBox1.Image = n.GetBitmap(); }
private void RefreshImage() { pictureBox1.Image?.Dispose(); var n = new NikseBitmap(_source); n.CropTopTransparent(9999); if (panelColorToWhite.BackColor != Color.Transparent) { n.ReplaceColor(panelColorToWhite.BackColor.A, panelColorToWhite.BackColor.R, panelColorToWhite.BackColor.G, panelColorToWhite.BackColor.B, 255, 255, 255, 255); } if (panelColorToRemove.BackColor != Color.Transparent) { n.ReplaceColor(panelColorToRemove.BackColor.A, panelColorToRemove.BackColor.R, panelColorToRemove.BackColor.G, panelColorToRemove.BackColor.B, Color.Transparent.A, Color.Transparent.R, Color.Transparent.G, Color.Transparent.B); } if (_isBinaryImageCompare) { n.MakeTwoColor((int)numericUpDownThreshold.Value); } pictureBox1.Image = n.GetBitmap(); }
public BinEditBrightness(Bitmap bitmap) { UiUtil.PreInitialize(this); InitializeComponent(); UiUtil.FixFonts(this); var nikseBitmap = new NikseBitmap(bitmap); nikseBitmap.CropTransparentSidesAndBottom(99999, true); nikseBitmap.CropTopTransparent(2); _bitmap = nikseBitmap.GetBitmap(); trackBarBrightness_Scroll(null, null); Factor = 1.0m; Alignment = ContentAlignment.BottomCenter; Text = LanguageSettings.Current.BinEdit.ChangeBrightnessTitle; labelChangeBrightness.Text = string.Format(LanguageSettings.Current.BinEdit.BrightnessX, trackBarBrightness.Value); buttonOK.Text = LanguageSettings.Current.General.Ok; buttonCancel.Text = LanguageSettings.Current.General.Cancel; UiUtil.FixLargeFonts(this, buttonOK); }
public BinEditAlpha(Bitmap bitmap) { UiUtil.PreInitialize(this); InitializeComponent(); UiUtil.FixFonts(this); var nikseBitmap = new NikseBitmap(bitmap); nikseBitmap.CropTransparentSidesAndBottom(99999, true); nikseBitmap.CropTopTransparent(2); _bitmap = nikseBitmap.GetBitmap(); _backgroundImageDark = Configuration.Settings.General.UseDarkTheme; trackBarAlpha_Scroll(null, null); Factor = 1.0m; Alignment = ContentAlignment.BottomCenter; Text = LanguageSettings.Current.BinEdit.ChangeAlphaTitle; labelChangeAlpha.Text = string.Format(LanguageSettings.Current.BinEdit.AlphaX, trackBarAlpha.Value); buttonOK.Text = LanguageSettings.Current.General.Ok; buttonCancel.Text = LanguageSettings.Current.General.Cancel; UiUtil.FixLargeFonts(this, buttonOK); }
/// <summary> /// The make blu ray sup image. /// </summary> /// <param name="param"> /// The param. /// </param> private static void MakeBluRaySupImage(MakeBitmapParameter param) { var brSub = new Logic.BluRaySup.BluRaySupPicture { StartTime = (long)param.P.StartTime.TotalMilliseconds, EndTime = (long)param.P.EndTime.TotalMilliseconds, Width = param.ScreenWidth, Height = param.ScreenHeight, IsForced = param.Forced }; if (param.FullFrame) { var nbmp = new NikseBitmap(param.Bitmap); nbmp.ReplaceTransparentWith(param.FullFrameBackgroundcolor); using (var bmp = nbmp.GetBitmap()) { int top = param.ScreenHeight - (param.Bitmap.Height + param.BottomMargin); int left = (param.ScreenWidth - param.Bitmap.Width) / 2; var b = new NikseBitmap(param.ScreenWidth, param.ScreenHeight); { b.Fill(param.FullFrameBackgroundcolor); using (var fullSize = b.GetBitmap()) { if (param.Alignment == ContentAlignment.BottomLeft || param.Alignment == ContentAlignment.MiddleLeft || param.Alignment == ContentAlignment.TopLeft) { left = param.LeftRightMargin; } else if (param.Alignment == ContentAlignment.BottomRight || param.Alignment == ContentAlignment.MiddleRight || param.Alignment == ContentAlignment.TopRight) { left = param.ScreenWidth - param.Bitmap.Width - param.LeftRightMargin; } if (param.Alignment == ContentAlignment.TopLeft || param.Alignment == ContentAlignment.TopCenter || param.Alignment == ContentAlignment.TopRight) { top = param.BottomMargin; } if (param.Alignment == ContentAlignment.MiddleLeft || param.Alignment == ContentAlignment.MiddleCenter || param.Alignment == ContentAlignment.MiddleRight) { top = param.ScreenHeight - (param.Bitmap.Height / 2); } using (var g = Graphics.FromImage(fullSize)) { g.DrawImage(bmp, left, top); g.Dispose(); } param.Buffer = Logic.BluRaySup.BluRaySupPicture.CreateSupFrame(brSub, fullSize, param.FramesPerSeconds, 0, 0, ContentAlignment.BottomCenter); } } } } else { param.Buffer = Logic.BluRaySup.BluRaySupPicture.CreateSupFrame(brSub, param.Bitmap, param.FramesPerSeconds, param.BottomMargin, param.LeftRightMargin, param.Alignment); } }
/// <summary> /// The to old bitmap. /// </summary> /// <returns> /// The <see cref="Bitmap"/>. /// </returns> public Bitmap ToOldBitmap() { if (this.ExpandedList != null && this.ExpandedList.Count > 0) { int minX = this.X; int minY = this.Y; int maxX = this.X + this.Width; int maxY = this.Y + this.Height; List<BinaryOcrBitmap> list = new List<BinaryOcrBitmap>(); list.Add(this); foreach (BinaryOcrBitmap bob in this.ExpandedList) { if (bob.X < minX) { minX = bob.X; } if (bob.Y < minY) { minY = bob.Y; } if (bob.X + bob.Width > maxX) { maxX = bob.X + bob.Width; } if (bob.Y + bob.Height > maxY) { maxY = bob.Y + bob.Height; } list.Add(bob); } BinaryOcrBitmap nbmp = new BinaryOcrBitmap(maxX - minX, maxY - minY); foreach (BinaryOcrBitmap bob in list) { for (int y = 0; y < bob.Height; y++) { for (int x = 0; x < bob.Width; x++) { int c = bob.GetPixel(x, y); if (c > 0) { nbmp.SetPixel(bob.X - minX + x, bob.Y - minY + y, 1); } } } } return nbmp.ToOldBitmap(); // Resursive } else { NikseBitmap nbmp = new NikseBitmap(this.Width, this.Height); for (int y = 0; y < this.Height; y++) { for (int x = 0; x < this.Width; x++) { Color c = Color.Transparent; if (this.GetPixel(x, y) > 0) { c = Color.White; } nbmp.SetPixel(x, y, c); } } return nbmp.GetBitmap(); } }
/// <summary> /// The generate preview. /// </summary> private void GeneratePreview() { this.SetupImageParameters(); if (this.subtitleListView1.SelectedItems.Count > 0) { MakeBitmapParameter mbp; var bmp = this.GenerateImageFromTextWithStyle(this._subtitle.Paragraphs[this.subtitleListView1.SelectedItems[0].Index], out mbp); if (this.checkBoxFullFrameImage.Visible && this.checkBoxFullFrameImage.Checked) { var nbmp = new NikseBitmap(bmp); nbmp.ReplaceTransparentWith(this.panelFullFrameBackground.BackColor); bmp.Dispose(); bmp = nbmp.GetBitmap(); } else { this.groupBoxExportImage.BackColor = DefaultBackColor; } this.pictureBox1.Image = bmp; int w = this.groupBoxExportImage.Width - 4; this.pictureBox1.Width = bmp.Width; this.pictureBox1.Height = bmp.Height; this.pictureBox1.Top = this.groupBoxExportImage.Height - bmp.Height - int.Parse(this.comboBoxBottomMargin.Text); this.pictureBox1.Left = (w - bmp.Width) / 2; var alignment = GetAlignmentFromParagraph(mbp, this._format, this._subtitle); // fix alignment from UI if (this.comboBoxHAlign.Visible && alignment == ContentAlignment.BottomCenter && this._format.GetType() != typeof(AdvancedSubStationAlpha) && this._format.GetType() != typeof(SubStationAlpha)) { if (this.comboBoxHAlign.SelectedIndex == 0) { alignment = ContentAlignment.BottomLeft; } else if (this.comboBoxHAlign.SelectedIndex == 2) { alignment = ContentAlignment.BottomRight; } } if (this.comboBoxHAlign.Visible) { if (this.comboBoxLeftRightMargin.Visible) { if (alignment == ContentAlignment.BottomLeft || alignment == ContentAlignment.MiddleLeft || alignment == ContentAlignment.TopLeft) { this.pictureBox1.Left = int.Parse(this.comboBoxLeftRightMargin.Text); } else if (alignment == ContentAlignment.BottomRight || alignment == ContentAlignment.MiddleRight || alignment == ContentAlignment.TopRight) { this.pictureBox1.Left = w - bmp.Width - int.Parse(this.comboBoxLeftRightMargin.Text); } } if (alignment == ContentAlignment.MiddleLeft || alignment == ContentAlignment.MiddleCenter || alignment == ContentAlignment.MiddleRight) { this.pictureBox1.Top = (this.groupBoxExportImage.Height - 4 - bmp.Height) / 2; } else if (this.comboBoxBottomMargin.Visible && alignment == ContentAlignment.TopLeft || alignment == ContentAlignment.TopCenter || alignment == ContentAlignment.TopRight) { this.pictureBox1.Top = int.Parse(this.comboBoxBottomMargin.Text); } } if (bmp.Width > this.groupBoxExportImage.Width + 20 || bmp.Height > this.groupBoxExportImage.Height + 20) { this.pictureBox1.Left = 5; this.pictureBox1.Top = 20; this.pictureBox1.Width = this.groupBoxExportImage.Width - 10; this.pictureBox1.Height = this.groupBoxExportImage.Height - 30; this.pictureBox1.SizeMode = PictureBoxSizeMode.Zoom; } else { this.pictureBox1.SizeMode = PictureBoxSizeMode.Normal; } this.groupBoxExportImage.Text = string.Format("{0}x{1}", bmp.Width, bmp.Height); if (!string.IsNullOrEmpty(mbp.Error)) { this.groupBoxExportImage.BackColor = Color.Red; this.groupBoxExportImage.Text = this.groupBoxExportImage.Text + " - " + mbp.Error; } else { if (this.checkBoxFullFrameImage.Visible && this.checkBoxFullFrameImage.Checked) { this.groupBoxExportImage.BackColor = this.panelFullFrameBackground.BackColor; } else { this.groupBoxExportImage.BackColor = this.groupBoxImageSettings.BackColor; } } } }
public Bitmap GetSubtitleBitmap(int index) { Bitmap returnBmp = null; Color background; Color pattern; Color emphasis1; Color emphasis2; if (_mp4List != null) { if (index >= 0 && index < _mp4List.Count) { 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 (index >= 0 && index < _spList.Count) { 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) { var fileNames = _bdnXmlSubtitle.Paragraphs[index].Text.SplitToLines(); 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)) { // fix AVISubDetector lines int idxOfIEquals = fn.IndexOf("i=", StringComparison.OrdinalIgnoreCase); if (idxOfIEquals >= 0) { int idxOfSpace = fn.IndexOf(' ', idxOfIEquals); if (idxOfSpace > 0) { fullFileName = Path.Combine(Path.GetDirectoryName(_bdnFileName), fn.Remove(0, idxOfSpace).Trim()); } } } 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 (index >= 0 && index < _xSubList.Count) { 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) { if (index >= 0 && index < _dvbSubtitles.Count) { var dvbBmp = _dvbSubtitles[index].GetActiveImage(); var nDvbBmp = new NikseBitmap(dvbBmp); nDvbBmp.CropTopTransparent(2); nDvbBmp.CropTransparentSidesAndBottom(2, true); if (checkBoxTransportStreamGetColorAndSplit.Checked) _dvbSubColor = nDvbBmp.GetBrightestColorWhiteIsTransparent(); if (checkBoxAutoTransparentBackground.Checked) nDvbBmp.MakeBackgroundTransparent((int)numericUpDownAutoTransparentAlphaMax.Value); if (checkBoxTransportStreamGrayscale.Checked) nDvbBmp.GrayScale(); dvbBmp.Dispose(); returnBmp = nDvbBmp.GetBitmap(); } } else if (_dvbPesSubtitles != null) { if (index >= 0 && index < _dvbPesSubtitles.Count) { var dvbBmp = _dvbPesSubtitles[index].GetImageFull(); var nDvbBmp = new NikseBitmap(dvbBmp); nDvbBmp.CropTopTransparent(2); nDvbBmp.CropTransparentSidesAndBottom(2, true); if (checkBoxTransportStreamGetColorAndSplit.Checked) _dvbSubColor = nDvbBmp.GetBrightestColorWhiteIsTransparent(); if (checkBoxAutoTransparentBackground.Checked) nDvbBmp.MakeBackgroundTransparent((int)numericUpDownAutoTransparentAlphaMax.Value); if (checkBoxTransportStreamGrayscale.Checked) nDvbBmp.GrayScale(); dvbBmp.Dispose(); returnBmp = nDvbBmp.GetBitmap(); } } else if (_bluRaySubtitlesOriginal != null) { if (index >= 0 && index < _bluRaySubtitles.Count) { returnBmp = _bluRaySubtitles[index].GetBitmap(); } } else if (index >= 0 && index < _vobSubMergedPackist.Count) { 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 (returnBmp == null) return null; if ((_binaryOcrDb == null && _nOcrDb == null) || _fromMenuItem) return returnBmp; var n = new NikseBitmap(returnBmp); n.MakeTwoColor(280); returnBmp.Dispose(); return n.GetBitmap(); }
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 string tempTiffFileName = Path.GetTempPath() + Guid.NewGuid() + ".png"; string tempTextFileName; using (var b = nbmp.GetBitmap()) { b.Save(tempTiffFileName, System.Drawing.Imaging.ImageFormat.Png); tempTextFileName = Path.GetTempPath() + Guid.NewGuid(); } using (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(); process.StartInfo.Arguments += " hocr"; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; if (Configuration.IsRunningOnLinux() || Configuration.IsRunningOnMac()) { process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardError = true; process.StartInfo.FileName = "tesseract"; } else { process.StartInfo.WorkingDirectory = (Configuration.TesseractFolder); } try { process.Start(); } catch { if (Configuration.IsRunningOnLinux() || Configuration.IsRunningOnMac()) { MessageBox.Show("Unable to start 'Tesseract' - make sure tesseract-ocr 3.x is installed!"); } else { MessageBox.Show("Unable to start 'Tesseract' (" + Configuration.TesseractFolder + "tesseract.exe) - make sure tesseract-ocr 3.x is installed!"); } throw; } process.WaitForExit(5000); } string result = string.Empty; string outputFileName = tempTextFileName + ".html"; if (!File.Exists(outputFileName)) outputFileName = tempTextFileName + ".hocr"; try { if (File.Exists(outputFileName)) { result = File.ReadAllText(outputFileName); result = ParseHocr(result); File.Delete(outputFileName); } File.Delete(tempTiffFileName); } catch { } return result; }
public static bool ConvertFromTsToBluRaySup(string fileName, string outputFolder, bool overwrite, StreamWriter stdOutWriter, CommandLineConverter.BatchConvertProgress progressCallback) { var tsParser = new TransportStreamParser(); tsParser.Parse(fileName, (position, total) => { var percent = (int)Math.Round(position * 100.0 / total); stdOutWriter?.Write("\rParsing transport stream: {0}%", percent); progressCallback?.Invoke($"{percent}%"); }); stdOutWriter?.Write("\r".PadRight(32, ' ')); stdOutWriter?.Write("\r"); var videoInfo = UiUtil.GetVideoInfo(fileName); int width = 720; int height = 576; if (videoInfo.Success && videoInfo.Width > 0 && videoInfo.Height > 0) { width = videoInfo.Width; height = videoInfo.Height; } var overrideScreenSize = Configuration.Settings.Tools.BatchConvertTsOverrideScreenSize && Configuration.Settings.Tools.BatchConvertTsScreenWidth > 0 && Configuration.Settings.Tools.BatchConvertTsScreenHeight > 0; if (overrideScreenSize) { width = Configuration.Settings.Tools.BatchConvertTsScreenWidth; height = Configuration.Settings.Tools.BatchConvertTsScreenHeight; } using (var form = new ExportPngXml()) { if (tsParser.SubtitlePacketIds.Count == 0) { stdOutWriter?.WriteLine($"No subtitles found"); progressCallback?.Invoke($"No subtitles found"); return(false); } form.Initialize(new Subtitle(), new SubRip(), BatchConvert.BluRaySubtitle, fileName, videoInfo, fileName); foreach (int pid in tsParser.SubtitlePacketIds) { var outputFileName = CommandLineConverter.FormatOutputFileNameForBatchConvert(Utilities.GetPathAndFileNameWithoutExtension(fileName) + "-" + pid + Path.GetExtension(fileName), ".sup", outputFolder, overwrite); stdOutWriter?.WriteLine($"Saving PID {pid} to {outputFileName}..."); var sub = tsParser.GetDvbSubtitles(pid); progressCallback?.Invoke($"Save PID {pid}"); using (var binarySubtitleFile = new FileStream(outputFileName, FileMode.Create)) { for (int index = 0; index < sub.Count; index++) { var p = sub[index]; var pos = p.GetPosition(); var bmp = sub[index].GetBitmap(); if (!overrideScreenSize) { width = bmp.Width; height = bmp.Height; videoInfo.Width = bmp.Width; videoInfo.Height = bmp.Height; } var tsWidth = bmp.Width; var tsHeight = bmp.Height; var nbmp = new NikseBitmap(bmp); pos.Top += nbmp.CropTopTransparent(0); pos.Left += nbmp.CropSidesAndBottom(0, Color.FromArgb(0, 0, 0, 0), true); bmp.Dispose(); bmp = nbmp.GetBitmap(); var mp = form.MakeMakeBitmapParameter(index, width, height); if (overrideScreenSize) { var widthFactor = (double)width / tsWidth; var heightFactor = (double)height / tsHeight; var resizeBmp = ResizeBitmap(bmp, (int)Math.Round(bmp.Width * widthFactor), (int)Math.Round(bmp.Height * heightFactor)); bmp.Dispose(); bmp = resizeBmp; pos.Left = (int)Math.Round(pos.Left * widthFactor); pos.Top = (int)Math.Round(pos.Top * heightFactor); progressCallback?.Invoke($"Save PID {pid}: {(index + 1) * 100 / sub.Count}%"); } mp.Bitmap = bmp; mp.P = new Paragraph(string.Empty, p.StartMilliseconds, p.EndMilliseconds); mp.ScreenWidth = width; mp.ScreenHeight = height; if (Configuration.Settings.Tools.BatchConvertTsOverrideXPosition || Configuration.Settings.Tools.BatchConvertTsOverrideYPosition) { var overrideMarginX = (int)Math.Round(Configuration.Settings.Tools.BatchConvertTsOverrideHMargin * width / 100.0); var overrideMarginY = (int)Math.Round(Configuration.Settings.Tools.BatchConvertTsOverrideBottomMargin * width / 100.0); if (Configuration.Settings.Tools.BatchConvertTsOverrideXPosition && Configuration.Settings.Tools.BatchConvertTsOverrideYPosition) { var x = (int)Math.Round((width / 2.0) - mp.Bitmap.Width / 2.0); if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("left", StringComparison.OrdinalIgnoreCase)) { x = overrideMarginX; } else if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("right", StringComparison.OrdinalIgnoreCase)) { x = width - overrideMarginX - mp.Bitmap.Width; } var y = height - overrideMarginY - mp.Bitmap.Height; mp.OverridePosition = new Point(x, y); } else if (Configuration.Settings.Tools.BatchConvertTsOverrideXPosition) { var x = (int)Math.Round((width / 2.0) - mp.Bitmap.Width / 2.0); if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("left", StringComparison.OrdinalIgnoreCase)) { x = overrideMarginX; } else if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("right", StringComparison.OrdinalIgnoreCase)) { x = width - overrideMarginX - mp.Bitmap.Width; } mp.OverridePosition = new Point(x, pos.Top); } else { var y = height - overrideMarginY - mp.Bitmap.Height; mp.OverridePosition = new Point(pos.Left, y); } } else { mp.OverridePosition = new Point(pos.Left, pos.Top); // use original position (can be scaled) } ExportPngXml.MakeBluRaySupImage(mp); binarySubtitleFile.Write(mp.Buffer, 0, mp.Buffer.Length); if (mp.Bitmap != null) { mp.Bitmap.Dispose(); mp.Bitmap = null; } } } } } return(true); }
private Bitmap GenerateImageFromTextWithStyle(string text, bool bold) { bool subtitleFontBold = bold; text = HtmlUtil.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(HtmlUtil.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); g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; g.SmoothingMode = SmoothingMode.AntiAlias; g.CompositingQuality = CompositingQuality.HighQuality; var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Near }; // draw the text to a path var path = new GraphicsPath(); // display italic var sb = new StringBuilder(); int i = 0; const float left = 5f; float top = 5; bool newLine = false; const float leftMargin = left; int newLinePathPoint = -1; Color c = _subtitleColor; int textLen = text.Length; while (i < textLen) { char ch = text[i]; if (ch == '\n' || ch == '\r') { TextDraw.DrawText(font, sf, path, sb, false, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); top += lineHeight; newLine = true; if (i + 1 < textLen && text[i + 1] == '\n' && text[i] == '\r') { i += 2; // CR+LF (Microsoft Windows) } else { i++; // LF (Unix and Unix-like systems ) } } else { sb.Append(ch); } i++; } if (sb.Length > 0) { TextDraw.DrawText(font, sf, path, sb, false, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); } sf.Dispose(); 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 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 { font = new Font(_subtitleFontName, _subtitleFontSize, FontStyle.Regular); } 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(HtmlUtil.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 (var line in HtmlUtil.RemoveOpenCloseTags(text, HtmlUtil.TagItalic, HtmlUtil.TagFont).SplitToLines()) { 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).StartsWith("<font ", StringComparison.OrdinalIgnoreCase)) { 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 < 0) { i += 9999; } else { string fontContent = text.Substring(i, endIndex); if (fontContent.Contains(" color=")) { var arr = fontContent.Substring(fontContent.IndexOf(" color=", StringComparison.Ordinal) + 7).Trim().Split(new[] { ' ' }, 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(new[] { ',' }, 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).StartsWith("</font>", StringComparison.OrdinalIgnoreCase)) { 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).StartsWith("<i>", StringComparison.OrdinalIgnoreCase)) { 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).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) && 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[i]); } 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(); }
public void WriteParagraph(Paragraph p, Bitmap bmp) { // timestamp: 00:00:33:900, filepos: 000000000 _idx.AppendLine(string.Format("timestamp: {0:00}:{1:00}:{2:00}:{3:000}, filepos: {4}", p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, p.StartTime.Milliseconds, _subFile.Position.ToString("X").PadLeft(9, '0'))); // write binary vobsub file (duration + image) long start = _subFile.Position; _subFile.Write(Mpeg2PackHeaderBuffer, 0, Mpeg2PackHeaderBuffer.Length); NikseBitmap nbmp = new NikseBitmap(bmp); nbmp.ConverToFourColors(Color.Transparent, Color.White, Color.FromArgb(200, 0, 0, 0), Color.FromArgb(200, 25, 25, 25)); var outBmp = nbmp.GetBitmap(); outBmp.Save(@"D:\download\-_-" + p.Number.ToString() + ".bmp"); bmp.Save(@"D:\download\-__" + p.Number.ToString() + ".bmp"); outBmp.Dispose(); var twoPartBuffer = nbmp.RunLengthEncodeForDvd(Color.Transparent, Color.White, Color.FromArgb(200, 0, 0, 0), Color.FromArgb(200, 25, 25, 25)); // PES size int length = Mpeg2PackHeaderBuffer.Length + PacketizedElementaryStreamHeaderBufferFirst.Length + 10 + twoPartBuffer.Length; //block_size = 0x800 - header_size; //long j = (header_size - 20) + block_size; //SubHeader[18] = (byte)(j / 0x100); //SubHeader[19] = (byte)(j % 0x100); PacketizedElementaryStreamHeaderBufferFirst[4] = (byte)(length / 256); PacketizedElementaryStreamHeaderBufferFirst[5] = (byte)(length % 256); _subFile.Write(PacketizedElementaryStreamHeaderBufferFirst, 0, PacketizedElementaryStreamHeaderBufferFirst.Length); // PTS (timestamp) FillPTS(p.StartTime); _subFile.Write(PresentationTimeStampBuffer, 0, PresentationTimeStampBuffer.Length); _subFile.WriteByte(0x32); //sub-stream number if (twoPartBuffer.Length < 0x800 - (_subFile.Position - start)) { _subFile.Write(twoPartBuffer.Buffer1, 0, twoPartBuffer.Buffer1.Length); _subFile.Write(twoPartBuffer.Buffer2, 0, twoPartBuffer.Buffer2.Length); } else { System.Windows.Forms.MessageBox.Show("Too long for payload!!!"); } // HeaderDataLength = buffer[index + 8]; // language id // int id = buffer[9 + HeaderDataLength]; // if (id >= 0x20 && id <= 0x40) // x3f 0r x40 ? // SubPictureStreamId = id; //} for (long i = _subFile.Position - start; i < 0x800; i++) // 2048 packet size - pad with 0xff { _subFile.WriteByte(0xff); } }
public static bool ConvertFromTsToBdnXml(string fileName, string outputFolder, bool overwrite, StreamWriter stdOutWriter, CommandLineConverter.BatchConvertProgress progressCallback) { var tsParser = new TransportStreamParser(); tsParser.Parse(fileName, (position, total) => { var percent = (int)Math.Round(position * 100.0 / total); stdOutWriter?.Write("\rParsing transport stream: {0}%", percent); progressCallback?.Invoke($"{percent}%"); }); stdOutWriter?.Write("\r".PadRight(32, ' ')); stdOutWriter?.Write("\r"); var videoInfo = UiUtil.GetVideoInfo(fileName); int width = 1920; int height = 1080; if (videoInfo.Success && videoInfo.Width > 0 && videoInfo.Height > 0) { width = videoInfo.Width; height = videoInfo.Height; } if (Configuration.Settings.Tools.BatchConvertTsOverrideScreenSize && Configuration.Settings.Tools.BatchConvertTsScreenWidth > 0 && Configuration.Settings.Tools.BatchConvertTsScreenHeight > 0) { width = Configuration.Settings.Tools.BatchConvertTsScreenWidth; height = Configuration.Settings.Tools.BatchConvertTsScreenHeight; } using (var form = new ExportPngXml()) { if (tsParser.SubtitlePacketIds.Count == 0) { stdOutWriter?.WriteLine($"No subtitles found"); progressCallback?.Invoke($"No subtitles found"); return(false); } foreach (int pid in tsParser.SubtitlePacketIds) { var outputFileName = CommandLineConverter.FormatOutputFileNameForBatchConvert(Utilities.GetPathAndFileNameWithoutExtension(fileName) + "-" + pid + Path.GetExtension(fileName), ".xml", outputFolder, overwrite); stdOutWriter?.WriteLine($"Saving PID {pid} to {outputFileName}..."); progressCallback?.Invoke($"Save PID {pid}"); var sub = tsParser.GetDvbSubtitles(pid); var subtitle = new Subtitle(); foreach (var p in sub) { subtitle.Paragraphs.Add(new Paragraph(string.Empty, p.StartMilliseconds, p.EndMilliseconds)); } form.Initialize(subtitle, new SubRip(), BatchConvert.BdnXmlSubtitle, fileName, videoInfo, fileName); var sb = new StringBuilder(); var imagesSavedCount = 0; for (int index = 0; index < sub.Count; index++) { var p = sub[index]; var pos = p.GetPosition(); var bmp = sub[index].GetBitmap(); var nbmp = new NikseBitmap(bmp); pos.Top += nbmp.CropTopTransparent(0); pos.Left += nbmp.CropSidesAndBottom(0, Color.FromArgb(0, 0, 0, 0), true); bmp.Dispose(); bmp = nbmp.GetBitmap(); var mp = form.MakeMakeBitmapParameter(index, width, height); mp.Bitmap = bmp; mp.P = new Paragraph(string.Empty, p.StartMilliseconds, p.EndMilliseconds); mp.ScreenWidth = width; mp.ScreenHeight = height; int bottomMarginInPixels; if (Configuration.Settings.Tools.BatchConvertTsOverridePosition || Configuration.Settings.Tools.BatchConvertTsOverrideScreenSize && Configuration.Settings.Tools.BatchConvertTsScreenWidth > 0 && Configuration.Settings.Tools.BatchConvertTsScreenHeight > 0) { mp.BottomMargin = Configuration.Settings.Tools.BatchConvertTsOverrideBottomMargin; bottomMarginInPixels = Configuration.Settings.Tools.BatchConvertTsOverrideBottomMargin; mp.Alignment = ContentAlignment.BottomCenter; } else { mp.OverridePosition = new Point(pos.Left, pos.Top); // use original position bottomMarginInPixels = Configuration.Settings.Tools.BatchConvertTsScreenHeight - pos.Top - mp.Bitmap.Height; } imagesSavedCount = form.WriteBdnXmlParagraph(width, sb, bottomMarginInPixels, height, imagesSavedCount, mp, index, Path.GetDirectoryName(outputFileName)); if (mp.Bitmap != null) { mp.Bitmap.Dispose(); mp.Bitmap = null; } } form.WriteBdnXmlFile(imagesSavedCount, sb, outputFileName); } } return(true); }
public Bitmap ToOldBitmap() { var nbmp = new NikseBitmap(Width, Height); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { Color c = Color.Transparent; if (this.GetPixel(x, y)) c = Color.White; nbmp.SetPixel(x, y, c); } } return nbmp.GetBitmap(); }
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(); }
public Bitmap ToOldBitmap() { if (ExpandedList != null && ExpandedList.Count > 0) { int minX = X; int minY = Y; int maxX = X + Width; int maxY = Y + Height; var list = new List<BinaryOcrBitmap>(); list.Add(this); foreach (BinaryOcrBitmap bob in ExpandedList) { if (bob.X < minX) minX = bob.X; if (bob.Y < minY) minY = bob.Y; if (bob.X + bob.Width > maxX) maxX = bob.X + bob.Width; if (bob.Y + bob.Height > maxY) maxY = bob.Y + bob.Height; list.Add(bob); } var nbmp = new BinaryOcrBitmap(maxX - minX, maxY - minY); foreach (BinaryOcrBitmap bob in list) { for (int y = 0; y < bob.Height; y++) { for (int x = 0; x < bob.Width; x++) { int c = bob.GetPixel(x, y); if (c > 0) nbmp.SetPixel(bob.X - minX + x, bob.Y - minY + y, 1); } } } return nbmp.ToOldBitmap(); // Resursive } else { var nbmp = new NikseBitmap(Width, Height); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { Color c = Color.Transparent; if (this.GetPixel(x, y) > 0) c = Color.White; nbmp.SetPixel(x, y, c); } } return nbmp.GetBitmap(); } }
internal static void WriteTrack(string fileName, string outputFolder, bool overwrite, StreamWriter stdOutWriter, CommandLineConverter.BatchConvertProgress progressCallback, Point?resolution, ProgramMapTableParser programMapTableParser, int pid, TransportStreamParser tsParser) { var overrideScreenSize = Configuration.Settings.Tools.BatchConvertTsOverrideScreenSize && Configuration.Settings.Tools.BatchConvertTsScreenHeight > 0 && Configuration.Settings.Tools.BatchConvertTsScreenWidth > 0 || resolution.HasValue; using (var form = new ExportPngXml()) { var language = TsToBluRaySup.GetFileNameEnding(programMapTableParser, pid); var nameNoExt = Utilities.GetFileNameWithoutExtension(fileName) + "." + language; var folder = Path.Combine(outputFolder, nameNoExt); if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } var outputFileName = CommandLineConverter.FormatOutputFileNameForBatchConvert(nameNoExt + Path.GetExtension(fileName), ".xml", folder, overwrite); stdOutWriter?.WriteLine($"Saving PID {pid} to {outputFileName}..."); progressCallback?.Invoke($"Save PID {pid}"); var sub = tsParser.GetDvbSubtitles(pid); var subtitle = new Subtitle(); foreach (var p in sub) { subtitle.Paragraphs.Add(new Paragraph(string.Empty, p.StartMilliseconds, p.EndMilliseconds)); } var res = TsToBluRaySup.GetSubtitleScreenSize(sub, overrideScreenSize, resolution); var videoInfo = new VideoInfo { Success = true, Width = res.X, Height = res.Y }; form.Initialize(subtitle, new SubRip(), BatchConvert.BdnXmlSubtitle, fileName, videoInfo, fileName); var sb = new StringBuilder(); var imagesSavedCount = 0; for (int index = 0; index < sub.Count; index++) { var p = sub[index]; var pos = p.GetPosition(); var bmp = sub[index].GetBitmap(); var tsWidth = bmp.Width; var tsHeight = bmp.Height; var nBmp = new NikseBitmap(bmp); pos.Top += nBmp.CropTopTransparent(0); pos.Left += nBmp.CropSidesAndBottom(0, Color.FromArgb(0, 0, 0, 0), true); bmp.Dispose(); bmp = nBmp.GetBitmap(); var mp = form.MakeMakeBitmapParameter(index, videoInfo.Width, videoInfo.Height); if (overrideScreenSize) { var widthFactor = (double)videoInfo.Width / tsWidth; var heightFactor = (double)videoInfo.Height / tsHeight; var resizeBmp = ResizeBitmap(bmp, (int)Math.Round(bmp.Width * widthFactor), (int)Math.Round(bmp.Height * heightFactor)); bmp.Dispose(); bmp = resizeBmp; pos.Left = (int)Math.Round(pos.Left * widthFactor); pos.Top = (int)Math.Round(pos.Top * heightFactor); progressCallback?.Invoke($"Save PID {pid}: {(index + 1) * 100 / sub.Count}%"); } mp.Bitmap = bmp; mp.P = new Paragraph(string.Empty, p.StartMilliseconds, p.EndMilliseconds); mp.ScreenWidth = videoInfo.Width; mp.ScreenHeight = videoInfo.Height; int bottomMarginInPixels; if (Configuration.Settings.Tools.BatchConvertTsOverrideXPosition || Configuration.Settings.Tools.BatchConvertTsOverrideYPosition) { if (Configuration.Settings.Tools.BatchConvertTsOverrideXPosition && Configuration.Settings.Tools.BatchConvertTsOverrideYPosition) { var x = (int)Math.Round(videoInfo.Width / 2.0 - mp.Bitmap.Width / 2.0); if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("left", StringComparison.OrdinalIgnoreCase)) { x = Configuration.Settings.Tools.BatchConvertTsOverrideHMargin; } else if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("right", StringComparison.OrdinalIgnoreCase)) { x = videoInfo.Width - Configuration.Settings.Tools.BatchConvertTsOverrideHMargin - mp.Bitmap.Width; } var y = videoInfo.Height - Configuration.Settings.Tools.BatchConvertTsOverrideBottomMargin - mp.Bitmap.Height; mp.OverridePosition = new Point(x, y); } else if (Configuration.Settings.Tools.BatchConvertTsOverrideXPosition) { var x = (int)Math.Round(videoInfo.Width / 2.0 - mp.Bitmap.Width / 2.0); if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("left", StringComparison.OrdinalIgnoreCase)) { x = Configuration.Settings.Tools.BatchConvertTsOverrideHMargin; } else if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("right", StringComparison.OrdinalIgnoreCase)) { x = videoInfo.Width - Configuration.Settings.Tools.BatchConvertTsOverrideHMargin - mp.Bitmap.Width; } mp.OverridePosition = new Point(x, pos.Top); } else { var y = videoInfo.Height - Configuration.Settings.Tools.BatchConvertTsOverrideBottomMargin - mp.Bitmap.Height; mp.OverridePosition = new Point(pos.Left, y); } bottomMarginInPixels = Configuration.Settings.Tools.BatchConvertTsScreenHeight - pos.Top - mp.Bitmap.Height; } else { mp.OverridePosition = new Point(pos.Left, pos.Top); // use original position bottomMarginInPixels = Configuration.Settings.Tools.BatchConvertTsScreenHeight - pos.Top - mp.Bitmap.Height; } imagesSavedCount = form.WriteBdnXmlParagraph(videoInfo.Width, sb, bottomMarginInPixels, videoInfo.Height, imagesSavedCount, mp, index, Path.GetDirectoryName(outputFileName)); } form.WriteBdnXmlFile(imagesSavedCount, sb, outputFileName); } }
/// <summary> /// The link label preview_ link clicked. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The e. /// </param> private void linkLabelPreview_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { this.linkLabelPreview.Enabled = false; this.Cursor = Cursors.WaitCursor; try { int width; int height; this.GetResolution(out width, out height); using (var bmp = new Bitmap(width, height)) { using (var g = Graphics.FromImage(bmp)) { var p = this._subtitle.Paragraphs[this.subtitleListView1.SelectedItems[0].Index]; this.FillPreviewBackground(bmp, g, p); var nBmp = new NikseBitmap(this.pictureBox1.Image as Bitmap); nBmp.CropSidesAndBottom(100, Color.Transparent, true); using (var textBmp = nBmp.GetBitmap()) { var bp = this.MakeMakeBitmapParameter(this.subtitleListView1.SelectedItems[0].Index, width, height); var alignment = GetAlignmentFromParagraph(bp, this._format, this._subtitle); if (this.comboBoxHAlign.Visible && alignment == ContentAlignment.BottomCenter && this._format.GetType() != typeof(AdvancedSubStationAlpha) && this._format.GetType() != typeof(SubStationAlpha)) { if (this.comboBoxHAlign.SelectedIndex == 0) { alignment = ContentAlignment.BottomLeft; } else if (this.comboBoxHAlign.SelectedIndex == 2) { alignment = ContentAlignment.BottomRight; } } int x = (bmp.Width - textBmp.Width) / 2; if (alignment == ContentAlignment.BottomLeft || alignment == ContentAlignment.MiddleLeft || alignment == ContentAlignment.TopLeft) { x = int.Parse(this.comboBoxBottomMargin.Text); } else if (alignment == ContentAlignment.BottomRight || alignment == ContentAlignment.MiddleRight || alignment == ContentAlignment.TopRight) { x = bmp.Width - textBmp.Width - int.Parse(this.comboBoxBottomMargin.Text); } int y = bmp.Height - textBmp.Height - int.Parse(this.comboBoxBottomMargin.Text); if (alignment == ContentAlignment.BottomLeft || alignment == ContentAlignment.MiddleLeft || alignment == ContentAlignment.TopLeft) { x = int.Parse(this.comboBoxBottomMargin.Text); } else if (alignment == ContentAlignment.BottomRight || alignment == ContentAlignment.MiddleRight || alignment == ContentAlignment.TopRight) { x = bmp.Width - textBmp.Width - int.Parse(this.comboBoxBottomMargin.Text); } if (alignment == ContentAlignment.MiddleLeft || alignment == ContentAlignment.MiddleCenter || alignment == ContentAlignment.MiddleRight) { y = (this.groupBoxExportImage.Height - 4 - textBmp.Height) / 2; } else if (alignment == ContentAlignment.TopLeft || alignment == ContentAlignment.TopCenter || alignment == ContentAlignment.TopRight) { y = int.Parse(this.comboBoxBottomMargin.Text); } g.DrawImageUnscaled(textBmp, new Point(x, y)); } } using (var form = new ExportPngXmlPreview(bmp)) { this.Cursor = Cursors.Default; form.ShowDialog(this); } } } finally { this.Cursor = Cursors.Default; this.linkLabelPreview.Enabled = true; } }
private Bitmap GenerateImageFromTextWithStyle(string text, bool bold) { bool subtitleFontBold = bold; text = HtmlUtil.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(HtmlUtil.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); 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; const float left = 5f; float top = 5; bool newLine = false; const float leftMargin = left; int newLinePathPoint = -1; Color c = _subtitleColor; while (i < text.Length) { if (text.Substring(i).StartsWith(Environment.NewLine)) { TextDraw.DrawText(font, sf, path, sb, false, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); top += lineHeight; newLine = true; i += Environment.NewLine.Length - 1; } else { sb.Append(text[i]); } i++; } if (sb.Length > 0) TextDraw.DrawText(font, sf, path, sb, false, 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 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> /// The write paragraph. /// </summary> /// <param name="width"> /// The width. /// </param> /// <param name="sb"> /// The sb. /// </param> /// <param name="border"> /// The border. /// </param> /// <param name="height"> /// The height. /// </param> /// <param name="imagesSavedCount"> /// The images saved count. /// </param> /// <param name="vobSubWriter"> /// The vob sub writer. /// </param> /// <param name="binarySubtitleFile"> /// The binary subtitle file. /// </param> /// <param name="param"> /// The param. /// </param> /// <param name="i"> /// The i. /// </param> /// <returns> /// The <see cref="int"/>. /// </returns> private int WriteParagraph(int width, StringBuilder sb, int border, int height, int imagesSavedCount, VobSubWriter vobSubWriter, FileStream binarySubtitleFile, MakeBitmapParameter param, int i) { if (param.Bitmap != null) { if (this._exportType == "BLURAYSUP") { if (!param.Saved) { binarySubtitleFile.Write(param.Buffer, 0, param.Buffer.Length); } param.Saved = true; } else if (this._exportType == "VOBSUB") { if (!param.Saved) { vobSubWriter.WriteParagraph(param.P, param.Bitmap, param.Alignment); } param.Saved = true; } else if (this._exportType == "FAB") { if (!param.Saved) { string numberString = string.Format("IMAGE{0:000}", i); string fileName = Path.Combine(this.folderBrowserDialog1.SelectedPath, numberString + "." + this.comboBoxImageFormat.Text.ToLower()); if (this.checkBoxFullFrameImage.Visible && this.checkBoxFullFrameImage.Checked) { var nbmp = new NikseBitmap(param.Bitmap); nbmp.ReplaceTransparentWith(this.panelFullFrameBackground.BackColor); using (var bmp = nbmp.GetBitmap()) { // param.Bitmap.Save(fileName, ImageFormat); imagesSavedCount++; // RACE001.TIF 00;00;02;02 00;00;03;15 000 000 720 480 // RACE002.TIF 00;00;05;18 00;00;09;20 000 000 720 480 int top = param.ScreenHeight - (param.Bitmap.Height + param.BottomMargin); int left = (param.ScreenWidth - param.Bitmap.Width) / 2; var b = new NikseBitmap(param.ScreenWidth, param.ScreenHeight); { b.Fill(this.panelFullFrameBackground.BackColor); using (var fullSize = b.GetBitmap()) { if (param.Alignment == ContentAlignment.BottomLeft || param.Alignment == ContentAlignment.MiddleLeft || param.Alignment == ContentAlignment.TopLeft) { left = param.LeftRightMargin; } else if (param.Alignment == ContentAlignment.BottomRight || param.Alignment == ContentAlignment.MiddleRight || param.Alignment == ContentAlignment.TopRight) { left = param.ScreenWidth - param.Bitmap.Width - param.LeftRightMargin; } if (param.Alignment == ContentAlignment.TopLeft || param.Alignment == ContentAlignment.TopCenter || param.Alignment == ContentAlignment.TopRight) { top = param.BottomMargin; } if (param.Alignment == ContentAlignment.MiddleLeft || param.Alignment == ContentAlignment.MiddleCenter || param.Alignment == ContentAlignment.MiddleRight) { top = param.ScreenHeight - (param.Bitmap.Height / 2); } using (var g = Graphics.FromImage(fullSize)) { g.DrawImage(bmp, left, top); g.Dispose(); } this.SaveImage(fullSize, fileName, this.ImageFormat); } } left = 0; top = 0; sb.AppendLine(string.Format("{0} {1} {2} {3} {4} {5} {6}", Path.GetFileName(fileName), FormatFabTime(param.P.StartTime, param), FormatFabTime(param.P.EndTime, param), left, top, left + param.ScreenWidth, top + param.ScreenHeight)); } } else { this.SaveImage(param.Bitmap, fileName, this.ImageFormat); imagesSavedCount++; // RACE001.TIF 00;00;02;02 00;00;03;15 000 000 720 480 // RACE002.TIF 00;00;05;18 00;00;09;20 000 000 720 480 int top = param.ScreenHeight - (param.Bitmap.Height + param.BottomMargin); int left = (param.ScreenWidth - param.Bitmap.Width) / 2; if (param.Alignment == ContentAlignment.BottomLeft || param.Alignment == ContentAlignment.MiddleLeft || param.Alignment == ContentAlignment.TopLeft) { left = param.LeftRightMargin; } else if (param.Alignment == ContentAlignment.BottomRight || param.Alignment == ContentAlignment.MiddleRight || param.Alignment == ContentAlignment.TopRight) { left = param.ScreenWidth - param.Bitmap.Width - param.LeftRightMargin; } if (param.Alignment == ContentAlignment.TopLeft || param.Alignment == ContentAlignment.TopCenter || param.Alignment == ContentAlignment.TopRight) { top = param.BottomMargin; } if (param.Alignment == ContentAlignment.MiddleLeft || param.Alignment == ContentAlignment.MiddleCenter || param.Alignment == ContentAlignment.MiddleRight) { top = param.ScreenHeight - (param.Bitmap.Height / 2); } sb.AppendLine(string.Format("{0} {1} {2} {3} {4} {5} {6}", Path.GetFileName(fileName), FormatFabTime(param.P.StartTime, param), FormatFabTime(param.P.EndTime, param), left, top, left + param.Bitmap.Width, top + param.Bitmap.Height)); } param.Saved = true; } } else if (this._exportType == "STL") { if (!param.Saved) { string numberString = string.Format("IMAGE{0:000}", i); string fileName = Path.Combine(this.folderBrowserDialog1.SelectedPath, numberString + "." + this.comboBoxImageFormat.Text.ToLower()); this.SaveImage(param.Bitmap, fileName, this.ImageFormat); imagesSavedCount++; const string paragraphWriteFormat = "{0} , {1} , {2}\r\n"; const string timeFormat = "{0:00}:{1:00}:{2:00}:{3:00}"; double factor = TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate; string startTime = string.Format(timeFormat, param.P.StartTime.Hours, param.P.StartTime.Minutes, param.P.StartTime.Seconds, (int)Math.Round(param.P.StartTime.Milliseconds / factor)); string endTime = string.Format(timeFormat, param.P.EndTime.Hours, param.P.EndTime.Minutes, param.P.EndTime.Seconds, (int)Math.Round(param.P.EndTime.Milliseconds / factor)); sb.AppendFormat(paragraphWriteFormat, startTime, endTime, fileName); param.Saved = true; } } else if (this._exportType == "SPUMUX") { if (!param.Saved) { string numberString = string.Format("IMAGE{0:000}", i); string fileName = Path.Combine(this.folderBrowserDialog1.SelectedPath, numberString + "." + this.comboBoxImageFormat.Text.ToLower()); foreach (var encoder in ImageCodecInfo.GetImageEncoders()) { if (encoder.FormatID == ImageFormat.Png.Guid) { var parameters = new EncoderParameters(); parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8); var nbmp = new NikseBitmap(param.Bitmap); var b = nbmp.ConverTo8BitsPerPixel(); b.Save(fileName, encoder, parameters); b.Dispose(); break; } } imagesSavedCount++; const string paragraphWriteFormat = "\t\t<spu start=\"{0}\" end=\"{1}\" image=\"{2}\" />"; const string timeFormat = "{0:00}:{1:00}:{2:00}:{3:00}"; double factor = TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate; string startTime = string.Format(timeFormat, param.P.StartTime.Hours, param.P.StartTime.Minutes, param.P.StartTime.Seconds, (int)Math.Round(param.P.StartTime.Milliseconds / factor)); string endTime = string.Format(timeFormat, param.P.EndTime.Hours, param.P.EndTime.Minutes, param.P.EndTime.Seconds, (int)Math.Round(param.P.EndTime.Milliseconds / factor)); sb.AppendLine(string.Format(paragraphWriteFormat, startTime, endTime, fileName)); param.Saved = true; } } else if (this._exportType == "FCP") { if (!param.Saved) { string numberString = string.Format(Path.GetFileNameWithoutExtension(Path.GetFileName(param.SavDialogFileName)) + "{0:0000}", i); string fileName = numberString + "." + this.comboBoxImageFormat.Text.ToLower(); string fileNameNoPath = Path.GetFileName(fileName); string fileNameNoExt = Path.GetFileNameWithoutExtension(fileNameNoPath); string template = " <clipitem id=\"" + fileNameNoPath + "\">" + Environment.NewLine + // <pathurl>file://localhost/" + fileNameNoPath.Replace(" ", "%20") + @"</pathurl> @" <name>" + fileNameNoPath + @"</name> <duration>[DURATION]</duration> <rate> <ntsc>FALSE</ntsc> <timebase>25</timebase> </rate> <in>[IN]</in> <out>[OUT]</out> <start>[START]</start> <end>[END]</end> <pixelaspectratio>" + param.VideoResolution + @"</pixelaspectratio> <stillframe>TRUE</stillframe> <anamorphic>FALSE</anamorphic> <alphatype>straight</alphatype> <masterclipid>" + fileNameNoPath + @"1</masterclipid>" + Environment.NewLine + " <file id=\"" + fileNameNoExt + "\">" + @" <name>" + fileNameNoPath + @"</name> <pathurl>" + fileNameNoPath.Replace(" ", "%20") + @"</pathurl> <rate> <timebase>25</timebase> </rate> <duration>[DURATION]</duration> <width>" + param.ScreenWidth + @"</width> <height>" + param.ScreenHeight + @"</height> <media> <video> <duration>[DURATION]</duration> <stillframe>TRUE</stillframe> <samplecharacteristics> <width>" + param.ScreenWidth + @"</width> <height>" + param.ScreenHeight + @"</height> </samplecharacteristics> </video> </media> </file> <sourcetrack> <mediatype>video</mediatype> </sourcetrack> <fielddominance>none</fielddominance> </clipitem>"; fileName = Path.Combine(Path.GetDirectoryName(param.SavDialogFileName), fileName); if (this.comboBoxImageFormat.Text == "8-bit png") { foreach (var encoder in ImageCodecInfo.GetImageEncoders()) { if (encoder.FormatID == ImageFormat.Png.Guid) { var parameters = new EncoderParameters(); parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8); var nbmp = new NikseBitmap(param.Bitmap); var b = nbmp.ConverTo8BitsPerPixel(); b.Save(fileName, encoder, parameters); b.Dispose(); break; } } } else { this.SaveImage(param.Bitmap, fileName, this.ImageFormat); } imagesSavedCount++; int duration = (int)Math.Round(param.P.Duration.TotalSeconds * param.FramesPerSeconds); int start = (int)Math.Round(param.P.StartTime.TotalSeconds * param.FramesPerSeconds); int end = (int)Math.Round(param.P.EndTime.TotalSeconds * param.FramesPerSeconds); template = template.Replace("[DURATION]", duration.ToString(CultureInfo.InvariantCulture)); template = template.Replace("[IN]", start.ToString(CultureInfo.InvariantCulture)); template = template.Replace("[OUT]", end.ToString(CultureInfo.InvariantCulture)); template = template.Replace("[START]", start.ToString(CultureInfo.InvariantCulture)); template = template.Replace("[END]", end.ToString(CultureInfo.InvariantCulture)); sb.AppendLine(template); param.Saved = true; } } else if (this._exportType == "DOST") { if (!param.Saved) { string numberString = string.Format("{0:0000}", i); string fileName = Path.Combine(Path.GetDirectoryName(this.saveFileDialog1.FileName), Path.GetFileNameWithoutExtension(this.saveFileDialog1.FileName).Replace(" ", "_")) + "_" + numberString + ".png"; foreach (var encoder in ImageCodecInfo.GetImageEncoders()) { if (encoder.FormatID == ImageFormat.Png.Guid) { var parameters = new EncoderParameters(); parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8); var nbmp = new NikseBitmap(param.Bitmap); var b = nbmp.ConverTo8BitsPerPixel(); b.Save(fileName, encoder, parameters); b.Dispose(); break; } } imagesSavedCount++; const string paragraphWriteFormat = "{0}\t{1}\t{2}\t{4}\t{5}\t{3}\t0\t0"; int top = param.ScreenHeight - (param.Bitmap.Height + param.BottomMargin); int left = (param.ScreenWidth - param.Bitmap.Width) / 2; if (param.Alignment == ContentAlignment.BottomLeft || param.Alignment == ContentAlignment.MiddleLeft || param.Alignment == ContentAlignment.TopLeft) { left = param.LeftRightMargin; } else if (param.Alignment == ContentAlignment.BottomRight || param.Alignment == ContentAlignment.MiddleRight || param.Alignment == ContentAlignment.TopRight) { left = param.ScreenWidth - param.Bitmap.Width - param.LeftRightMargin; } if (param.Alignment == ContentAlignment.TopLeft || param.Alignment == ContentAlignment.TopCenter || param.Alignment == ContentAlignment.TopRight) { top = param.BottomMargin; } if (param.Alignment == ContentAlignment.MiddleLeft || param.Alignment == ContentAlignment.MiddleCenter || param.Alignment == ContentAlignment.MiddleRight) { top = param.ScreenHeight - (param.Bitmap.Height / 2); } string startTime = this.BdnXmlTimeCode(param.P.StartTime); string endTime = this.BdnXmlTimeCode(param.P.EndTime); sb.AppendLine(string.Format(paragraphWriteFormat, numberString, startTime, endTime, Path.GetFileName(fileName), left, top)); param.Saved = true; } } else if (this._exportType == "IMAGE/FRAME") { if (!param.Saved) { var imageFormat = this.ImageFormat; int lastFrame = imagesSavedCount; int startFrame = (int)Math.Round(param.P.StartTime.TotalMilliseconds / (TimeCode.BaseUnit / param.FramesPerSeconds)); var empty = new Bitmap(param.ScreenWidth, param.ScreenHeight); if (imagesSavedCount == 0 && this.checkBoxSkipEmptyFrameAtStart.Checked) { } else { // Save empty picture for each frame up to start frame for (int k = lastFrame + 1; k < startFrame; k++) { string numberString = string.Format("{0:00000}", k); string fileName = Path.Combine(this.folderBrowserDialog1.SelectedPath, numberString + "." + this.comboBoxImageFormat.Text.ToLower()); empty.Save(fileName, imageFormat); imagesSavedCount++; } } int endFrame = (int)Math.Round(param.P.EndTime.TotalMilliseconds / (TimeCode.BaseUnit / param.FramesPerSeconds)); var fullSize = new Bitmap(param.ScreenWidth, param.ScreenHeight); Graphics g = Graphics.FromImage(fullSize); g.DrawImage(param.Bitmap, (param.ScreenWidth - param.Bitmap.Width) / 2, param.ScreenHeight - (param.Bitmap.Height + param.BottomMargin)); g.Dispose(); if (imagesSavedCount > startFrame) { startFrame = imagesSavedCount; // no overlapping } // Save sub picture for each frame in duration for (int k = startFrame; k <= endFrame; k++) { string numberString = string.Format("{0:00000}", k); string fileName = Path.Combine(this.folderBrowserDialog1.SelectedPath, numberString + "." + this.comboBoxImageFormat.Text.ToLower()); fullSize.Save(fileName, imageFormat); imagesSavedCount++; } fullSize.Dispose(); param.Saved = true; } } else if (this._exportType == "DCINEMA_INTEROP") { if (!param.Saved) { string numberString = string.Format("{0:0000}", i); string fileName = Path.Combine(Path.GetDirectoryName(this.saveFileDialog1.FileName), numberString + ".png"); param.Bitmap.Save(fileName, ImageFormat.Png); imagesSavedCount++; param.Saved = true; sb.AppendLine("<Subtitle FadeDownTime=\"" + 0 + "\" FadeUpTime=\"" + 0 + "\" TimeOut=\"" + DCSubtitle.ConvertToTimeString(param.P.EndTime) + "\" TimeIn=\"" + DCSubtitle.ConvertToTimeString(param.P.StartTime) + "\" SpotNumber=\"" + param.P.Number + "\">"); if (param.Depth3D == 0) { sb.AppendLine("<Image VPosition=\"9.7\" VAlign=\"bottom\" HAlign=\"center\">" + numberString + ".png" + "</Image>"); } else { sb.AppendLine("<Image VPosition=\"9.7\" ZPosition=\"" + param.Depth3D + "\" VAlign=\"bottom\" HAlign=\"center\">" + numberString + ".png" + "</Image>"); } sb.AppendLine("</Subtitle>"); } } else if (this._exportType == "EDL") { if (!param.Saved) { // 001 7M6C7986 V C 14:14:55:21 14:15:16:24 01:00:10:18 01:00:31:21 var fileName1 = "IMG" + i.ToString(CultureInfo.InvariantCulture).PadLeft(5, '0'); var fullSize = new Bitmap(param.ScreenWidth, param.ScreenHeight); using (var g = Graphics.FromImage(fullSize)) { g.DrawImage(param.Bitmap, (param.ScreenWidth - param.Bitmap.Width) / 2, param.ScreenHeight - (param.Bitmap.Height + param.BottomMargin)); } var fileName2 = Path.Combine(Path.GetDirectoryName(param.SavDialogFileName), fileName1 + ".PNG"); fullSize.Save(fileName2, ImageFormat.Png); fullSize.Dispose(); string line = string.Format("{0:000} {1} V C {2} {3} {4} {5}", i, fileName1, new TimeCode(0).ToHHMMSSFF(), param.P.Duration.ToHHMMSSFF(), param.P.StartTime.ToHHMMSSFF(), param.P.EndTime.ToHHMMSSFF()); sb.AppendLine(line); sb.AppendLine(); imagesSavedCount++; param.Saved = true; } } else { // BDNXML if (!param.Saved) { string numberString = string.Format("{0:0000}", i); string fileName = Path.Combine(this.folderBrowserDialog1.SelectedPath, numberString + ".png"); if (this.comboBoxImageFormat.Text == "Png 8-bit") { foreach (var encoder in ImageCodecInfo.GetImageEncoders()) { if (encoder.FormatID == ImageFormat.Png.Guid) { var parameters = new EncoderParameters(); parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8); var nbmp = new NikseBitmap(param.Bitmap); var b = nbmp.ConverTo8BitsPerPixel(); b.Save(fileName, encoder, parameters); b.Dispose(); break; } } } else { param.Bitmap.Save(fileName, ImageFormat.Png); } imagesSavedCount++; // <Event InTC="00:00:24:07" OutTC="00:00:31:13" Forced="False"> // <Graphic Width="696" Height="111" X="612" Y="930">subtitle_exp_0001.png</Graphic> // </Event> sb.AppendLine("<Event InTC=\"" + this.BdnXmlTimeCode(param.P.StartTime) + "\" OutTC=\"" + this.BdnXmlTimeCode(param.P.EndTime) + "\" Forced=\"" + param.Forced.ToString().ToLower() + "\">"); int x = (width - param.Bitmap.Width) / 2; int y = height - (param.Bitmap.Height + param.BottomMargin); switch (param.Alignment) { case ContentAlignment.BottomLeft: x = border; y = height - (param.Bitmap.Height + param.BottomMargin); break; case ContentAlignment.BottomRight: x = height - param.Bitmap.Width - border; y = height - (param.Bitmap.Height + param.BottomMargin); break; case ContentAlignment.MiddleCenter: x = (width - param.Bitmap.Width) / 2; y = (height - param.Bitmap.Height) / 2; break; case ContentAlignment.MiddleLeft: x = border; y = (height - param.Bitmap.Height) / 2; break; case ContentAlignment.MiddleRight: x = width - param.Bitmap.Width - border; y = (height - param.Bitmap.Height) / 2; break; case ContentAlignment.TopCenter: x = (width - param.Bitmap.Width) / 2; y = border; break; case ContentAlignment.TopLeft: x = border; y = border; break; case ContentAlignment.TopRight: x = width - param.Bitmap.Width - border; y = border; break; } sb.AppendLine(" <Graphic Width=\"" + param.Bitmap.Width.ToString(CultureInfo.InvariantCulture) + "\" Height=\"" + param.Bitmap.Height.ToString(CultureInfo.InvariantCulture) + "\" X=\"" + x.ToString(CultureInfo.InvariantCulture) + "\" Y=\"" + y.ToString(CultureInfo.InvariantCulture) + "\">" + numberString + ".png</Graphic>"); sb.AppendLine("</Event>"); param.Saved = true; } } } return imagesSavedCount; }
public Bitmap ToOldBitmap() { if (ExpandedList != null && ExpandedList.Count > 0) { int minX = X; int minY = Y; int maxX = X + Width; int maxY = Y + Height; var list = new List <BinaryOcrBitmap>(); list.Add(this); foreach (BinaryOcrBitmap bob in ExpandedList) { if (bob.X < minX) { minX = bob.X; } if (bob.Y < minY) { minY = bob.Y; } if (bob.X + bob.Width > maxX) { maxX = bob.X + bob.Width; } if (bob.Y + bob.Height > maxY) { maxY = bob.Y + bob.Height; } list.Add(bob); } var nbmp = new BinaryOcrBitmap(maxX - minX, maxY - minY); foreach (BinaryOcrBitmap bob in list) { for (int y = 0; y < bob.Height; y++) { for (int x = 0; x < bob.Width; x++) { int c = bob.GetPixel(x, y); if (c > 0) { nbmp.SetPixel(bob.X - minX + x, bob.Y - minY + y, 1); } } } } return(nbmp.ToOldBitmap()); // Resursive } else { var nbmp = new NikseBitmap(Width, Height); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { Color c = Color.Transparent; if (this.GetPixel(x, y) > 0) { c = Color.White; } nbmp.SetPixel(x, y, c); } } return(nbmp.GetBitmap()); } }
/// <summary> /// The generate image from text with style. /// </summary> /// <param name="p"> /// The p. /// </param> /// <param name="mbp"> /// The mbp. /// </param> /// <returns> /// The <see cref="Bitmap"/>. /// </returns> private Bitmap GenerateImageFromTextWithStyle(Paragraph p, out MakeBitmapParameter mbp) { mbp = new MakeBitmapParameter(); mbp.P = p; if (this._vobSubOcr != null) { var index = this._subtitle.GetIndex(p); if (index >= 0) { return this._vobSubOcr.GetSubtitleBitmap(index); } } mbp.AlignLeft = this.comboBoxHAlign.SelectedIndex == 0; mbp.AlignRight = this.comboBoxHAlign.SelectedIndex == 2; mbp.SimpleRendering = this.checkBoxSimpleRender.Checked; mbp.BorderWidth = this._borderWidth; mbp.BorderColor = this._borderColor; mbp.SubtitleFontName = this._subtitleFontName; mbp.SubtitleColor = this._subtitleColor; mbp.SubtitleFontSize = this._subtitleFontSize; mbp.SubtitleFontBold = this._subtitleFontBold; mbp.LineHeight = (int)this.numericUpDownLineSpacing.Value; mbp.FullFrame = this.checkBoxFullFrameImage.Checked; mbp.FullFrameBackgroundcolor = this.panelFullFrameBackground.BackColor; if (this._format.HasStyleSupport && !string.IsNullOrEmpty(p.Extra)) { if (this._format.GetType() == typeof(SubStationAlpha)) { var style = AdvancedSubStationAlpha.GetSsaStyle(p.Extra, this._subtitle.Header); mbp.SubtitleColor = style.Primary; mbp.SubtitleFontBold = style.Bold; mbp.SubtitleFontSize = style.FontSize; if (style.BorderStyle == "3") { mbp.BackgroundColor = style.Background; } } else if (this._format.GetType() == typeof(AdvancedSubStationAlpha)) { var style = AdvancedSubStationAlpha.GetSsaStyle(p.Extra, this._subtitle.Header); mbp.SubtitleColor = style.Primary; mbp.SubtitleFontBold = style.Bold; mbp.SubtitleFontSize = style.FontSize; if (style.BorderStyle == "3") { mbp.BackgroundColor = style.Outline; } } } if (this.comboBoxBorderWidth.SelectedItem.ToString() == Configuration.Settings.Language.ExportPngXml.BorderStyleBoxForEachLine) { this._borderWidth = 0; mbp.BackgroundColor = this.panelBorderColor.BackColor; mbp.BoxSingleLine = true; } else if (this.comboBoxBorderWidth.SelectedItem.ToString() == Configuration.Settings.Language.ExportPngXml.BorderStyleOneBox) { this._borderWidth = 0; mbp.BackgroundColor = this.panelBorderColor.BackColor; } int width; int height; this.GetResolution(out width, out height); mbp.ScreenWidth = width; mbp.ScreenHeight = height; mbp.VideoResolution = this.comboBoxResolution.Text; mbp.Type3D = this.comboBox3D.SelectedIndex; mbp.Depth3D = (int)this.numericUpDownDepth3D.Value; mbp.BottomMargin = this.comboBoxBottomMargin.SelectedIndex; mbp.ShadowWidth = this.comboBoxShadowWidth.SelectedIndex; mbp.ShadowAlpha = (int)this.numericUpDownShadowTransparency.Value; mbp.ShadowColor = this.panelShadowColor.BackColor; mbp.LineHeight = (int)this.numericUpDownLineSpacing.Value; mbp.Forced = this.subtitleListView1.Items[this._subtitle.GetIndex(p)].Checked; mbp.LineJoin = Configuration.Settings.Tools.ExportPenLineJoin; var bmp = GenerateImageFromTextWithStyle(mbp); if (this._exportType == "VOBSUB" || this._exportType == "STL" || this._exportType == "SPUMUX") { var nbmp = new NikseBitmap(bmp); nbmp.ConverToFourColors(Color.Transparent, this._subtitleColor, this._borderColor, !this.checkBoxTransAntiAliase.Checked); var temp = nbmp.GetBitmap(); bmp.Dispose(); return temp; } return bmp; }
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 { font = new Font(_subtitleFontName, _subtitleFontSize, FontStyle.Regular); } 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 (var line in HtmlUtil.RemoveOpenCloseTags(text, HtmlUtil.TagItalic, HtmlUtil.TagFont).Split(Utilities.NewLineChars, 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).StartsWith("<font ", StringComparison.OrdinalIgnoreCase)) { 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 < 0) { i += 9999; } else { string fontContent = text.Substring(i, endIndex); if (fontContent.Contains(" color=")) { var arr = fontContent.Substring(fontContent.IndexOf(" color=", StringComparison.Ordinal) + 7).Trim().Split(new[] { ' ' }, 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(new[] { ',' }, 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).StartsWith("</font>", StringComparison.OrdinalIgnoreCase)) { 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).StartsWith("<i>", StringComparison.OrdinalIgnoreCase)) { 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).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) && 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[i]); } 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()); }
/// <summary> /// The generate image from text with style inner. /// </summary> /// <param name="parameter"> /// The parameter. /// </param> /// <returns> /// The <see cref="Bitmap"/>. /// </returns> 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 = HtmlUtil.FixInvalidItalicTags(text); text = text.Replace("<B>", "<b>"); text = text.Replace("</B>", "</b>"); // no support for underline text = HtmlUtil.RemoveOpenCloseTags(text, HtmlUtil.TagUnderline); Font font = null; Bitmap bmp = null; try { font = SetFont(parameter, parameter.SubtitleFontSize); var lineHeight = parameter.LineHeight; // (textSize.Height * 0.64f); SizeF textSize; using (var bmpTemp = new Bitmap(1, 1)) using (var g = Graphics.FromImage(bmpTemp)) { textSize = g.MeasureString(HtmlUtil.RemoveHtmlTags(text), font); } 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; } if (parameter.BackgroundColor != Color.Transparent) { var nbmpTemp = new NikseBitmap(sizeX, sizeY); nbmpTemp.Fill(parameter.BackgroundColor); bmp = nbmpTemp.GetBitmap(); } else { bmp = new Bitmap(sizeX, sizeY); } // align lines with gjpqy, a bit lower var lines = text.SplitToLines(); int baseLinePadding = 13; if (parameter.SubtitleFontSize < 30) { baseLinePadding = 12; } if (parameter.SubtitleFontSize < 25) { baseLinePadding = 9; } if (lines.Length > 0) { var lastLine = lines[lines.Length - 1]; if (lastLine.Contains(new[] { 'g', 'j', 'p', 'q', 'y', ',', 'ý', 'ę', 'ç', 'Ç' })) { var textNoBelow = lastLine.Replace('g', 'a').Replace('j', 'a').Replace('p', 'a').Replace('q', 'a').Replace('y', 'a').Replace(',', 'a').Replace('ý', 'a').Replace('ę', 'a').Replace('ç', 'a').Replace('Ç', 'a'); baseLinePadding -= (int)Math.Round(TextDraw.MeasureTextHeight(font, lastLine, 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.Contains("<font", StringComparison.OrdinalIgnoreCase) || text.Contains("<i>", StringComparison.OrdinalIgnoreCase)) { foreach (string line in text.SplitToLines()) { var lineNoHtml = HtmlUtil.RemoveOpenCloseTags(line, HtmlUtil.TagItalic, HtmlUtil.TagFont); 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((float)((bmp.Width - CalcWidthViaDraw(lineNoHtml, parameter) + 5.0) / 2.0)); // calculate via drawing+crop } } } else { foreach (var line in HtmlUtil.RemoveOpenCloseTags(text, HtmlUtil.TagItalic, HtmlUtil.TagFont).SplitToLines()) { if (parameter.AlignLeft) { lefts.Add(5); } else if (parameter.AlignRight) { lefts.Add(bmp.Width - (TextDraw.MeasureTextWidth(font, line, parameter.SubtitleFontBold) + 15)); } else { lefts.Add((float)((bmp.Width - TextDraw.MeasureTextWidth(font, line, parameter.SubtitleFontBold) + 15) / 2.0)); } } } var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Near }; using (var g = Graphics.FromImage(bmp)) { g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; if (parameter.SimpleRendering) { if (text.StartsWith("<font ", StringComparison.Ordinal) && Utilities.CountTagInText(text, "<font") == 1) { parameter.SubtitleColor = Utilities.GetColorFromFontString(text, parameter.SubtitleColor); } text = HtmlUtil.RemoveHtmlTags(text, true); // TODO: Perhaps check single color... var brush = new SolidBrush(parameter.BorderColor); int x = 3; const 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(); 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(); int numberOfCharsOnCurrentLine = 0; for (var i = 0; i < text.Length; i++) { if (text.Substring(i).StartsWith("<font ", StringComparison.OrdinalIgnoreCase)) { 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) { var 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('>'); if (endIndex < 0) { 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(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string fontColor = arr[0].Trim('\'').Trim('"').Trim('\''); try { colorStack.Push(c); // save old color if (fontColor.StartsWith("rgb(", StringComparison.Ordinal)) { arr = fontColor.Remove(0, 4).TrimEnd(')').Split(new[] { ',' }, 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).StartsWith("</font>", StringComparison.OrdinalIgnoreCase)) { 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) { 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) { var 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).StartsWith("<i>", StringComparison.OrdinalIgnoreCase)) { if (sb.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).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) && isItalic) { if (lastText.EndsWith(' ') && !sb.StartsWith(' ')) { string t = sb.ToString(); sb.Clear(); sb.Append(' '); 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).StartsWith("<b>", StringComparison.OrdinalIgnoreCase)) { if (sb.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).StartsWith("</b>", StringComparison.OrdinalIgnoreCase) && isBold) { if (lastText.EndsWith(' ') && !sb.StartsWith(' ')) { string t = sb.ToString(); sb.Clear(); sb.Append(' '); 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, StringComparison.Ordinal)) { 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; } numberOfCharsOnCurrentLine = 0; } else { if (numberOfCharsOnCurrentLine != 0 || text[i] != ' ') { sb.Append(text[i]); numberOfCharsOnCurrentLine++; } } } 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); } } 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(); var 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(); } finally { if (font != null) { font.Dispose(); } if (bmp != null) { bmp.Dispose(); } } }
private string OcrViaTesseract(Bitmap bitmap, int index) { if (bitmap == null) return string.Empty; if (_ocrFixEngine == null) comboBoxDictionaries_SelectedIndexChanged(null, null); const int badWords = 0; string textWithOutFixes; if (_tesseractAsyncStrings != null && !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(textWithOutFixes, '\n') > 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 (string.IsNullOrWhiteSpace(textWithOutFixes)) { 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 (_ocrFixEngine != null && !psm.Contains('$') && !psm.Contains('•') && !psm.Contains('€')) { int correctWordsNoFixes; int wordsNotFoundNoFixes = _ocrFixEngine.CountUnknownWordsViaDictionary(textWithOutFixes, out correctWordsNoFixes); int correctWordsPsm7; int wordsNotFoundPsm7 = _ocrFixEngine.CountUnknownWordsViaDictionary(psm, out correctWordsPsm7); if (wordsNotFoundPsm7 <= wordsNotFoundNoFixes && correctWordsPsm7 > correctWordsNoFixes) { 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 = HtmlUtil.RemoveOpenCloseTags(textWithOutFixes, HtmlUtil.TagItalic); // Sometimes Tesseract has problems with small fonts - it helps to make the image larger if (HtmlUtil.RemoveOpenCloseTags(textWithOutFixes, HtmlUtil.TagItalic).Replace("@", string.Empty).Replace("%", string.Empty).Replace("|", string.Empty).Trim().Length < 3 || Utilities.CountTagInText(textWithOutFixes, '\n') > 2) { string rs = TesseractResizeAndRetry(bitmap); textWithOutFixes = rs; if (!checkBoxTesseractItalicsOn.Checked) textWithOutFixes = HtmlUtil.RemoveOpenCloseTags(textWithOutFixes, HtmlUtil.TagItalic); } // fix italics textWithOutFixes = FixItalics(textWithOutFixes); int numberOfWords = textWithOutFixes.Split((" " + Environment.NewLine).ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length; string line = textWithOutFixes.Trim(); if (_ocrFixEngine.IsDictionaryLoaded) { if (checkBoxAutoFixCommonErrors.Checked) line = _ocrFixEngine.FixOcrErrors(line, index, _lastLine, true, GetAutoGuessLevel()); 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, GetAutoGuessLevel()); 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 (correctWords >= oldCorrectWords && (!newText.Contains('9') || textWithOutFixes.Contains('9')) && (!newText.Replace("</i>", string.Empty).Contains('/') || textWithOutFixes.Replace("</i>", string.Empty).Contains('/')) && !string.IsNullOrWhiteSpace(newUnfixedText) && 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.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.GetNumberOfLines(oneColorText) < 4) { int modiCorrectWords; int modiWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(oneColorText, out modiCorrectWords); string modiTextOcrFixed = oneColorText; if (checkBoxAutoFixCommonErrors.Checked) modiTextOcrFixed = _ocrFixEngine.FixOcrErrors(oneColorText, index, _lastLine, false, GetAutoGuessLevel()); 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, GetAutoGuessLevel()); } 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, GetAutoGuessLevel()); } } } } if (checkBoxTesseractItalicsOn.Checked) { if (line.Contains("<i>") || wordsNotFound > 0 || correctWords == 0 || textWithOutFixes != null && textWithOutFixes.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, GetAutoGuessLevel()); 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 = HtmlUtil.RemoveOpenCloseTags(line, HtmlUtil.TagItalic).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 && HtmlUtil.RemoveOpenCloseTags(unItalicText, HtmlUtil.TagItalic).Substring(1, 2) == "' ") { unItalicText = "♪ " + unItalicText.Remove(0, 2).TrimStart(); } if ((line.StartsWith("J' ") || line.StartsWith("J“ ") || line.StartsWith("J* ") || line.StartsWith("♪ ")) && unItalicText.Length > 3 && HtmlUtil.RemoveOpenCloseTags(unItalicText, HtmlUtil.TagItalic)[1] == ' ') { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = HtmlUtil.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 && HtmlUtil.RemoveOpenCloseTags(unItalicText, HtmlUtil.TagItalic)[2] == ' ') { bool ita = unItalicText.StartsWith("<i>") && unItalicText.EndsWith("</i>"); unItalicText = HtmlUtil.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 = HtmlUtil.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 = HtmlUtil.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 = HtmlUtil.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 = HtmlUtil.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 = HtmlUtil.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 = HtmlUtil.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])) { 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])) { 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 = HtmlUtil.RemoveOpenCloseTags(unItalicText, HtmlUtil.TagItalic); 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, GetAutoGuessLevel()); } line = "<i>" + line + "</i>"; } else { unItalicText = unItalicText.Replace("</i>", string.Empty); if (line.EndsWith("</i>", StringComparison.Ordinal) && unItalicText.EndsWith('.')) { line = line.Remove(line.Length - 4, 4); if (line.EndsWith('-')) line = line.TrimEnd('-') + "."; if (char.IsLetter(line[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.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.GetNumberOfLines(modiText) < 4) { int modiWordsNotFound = _ocrFixEngine.CountUnknownWordsViaDictionary(modiText, out correctWords); //if (modiWordsNotFound > 0) { string modiTextOcrFixed = modiText; if (checkBoxAutoFixCommonErrors.Checked) modiTextOcrFixed = _ocrFixEngine.FixOcrErrors(modiText, index, _lastLine, false, GetAutoGuessLevel()); 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, GetAutoGuessLevel()); } else { // fix some error manually (modi not available) line = _ocrFixEngine.FixUnknownWordsViaGuessOrPrompt(out wordsNotFound, line, index, bitmap, checkBoxAutoFixCommonErrors.Checked, checkBoxPromptForUnknownWords.Checked, true, GetAutoGuessLevel()); } } if (_ocrFixEngine.Abort) { ButtonStopClick(null, null); _ocrFixEngine.Abort = false; return string.Empty; } //check Tesseract... find an other way to do this... //string tmp = HtmlUtil.RemoveHtmlTags(line).Trim(); //if (!tmp.TrimEnd().EndsWith("...")) //{ // tmp = tmp.TrimEnd('.').TrimEnd(); // if (tmp.Length > 2 && Utilities.LowercaseLetters.Contains(tmp[tmp.Length - 1])) // { // if (_nocrChars == null) // _nocrChars = LoadNOcrForTesseract("Nikse.SubtitleEdit.Resources.nOCR_TesseractHelper.xml.zip"); // string text = HtmlUtil.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(); ColorLineByNumberOfUnknownWords(index, wordsNotFound, line); } else { // no dictionary :( if (checkBoxAutoFixCommonErrors.Checked) line = _ocrFixEngine.FixOcrErrors(line, index, _lastLine, true, GetAutoGuessLevel()); if (badWords >= numberOfWords) subtitleListView1.SetBackgroundColor(index, Color.Red); else if (badWords >= numberOfWords / 2) subtitleListView1.SetBackgroundColor(index, Color.Orange); else if (badWords > 0 || line.Contains('_') || HasSingleLetters(line)) subtitleListView1.SetBackgroundColor(index, Color.Yellow); else if (string.IsNullOrWhiteSpace(HtmlUtil.RemoveOpenCloseTags(line, HtmlUtil.TagItalic))) subtitleListView1.SetBackgroundColor(index, Color.Orange); else subtitleListView1.SetBackgroundColor(index, Color.LightGreen); } if (textWithOutFixes.Trim() != line.Trim()) { _tesseractOcrAutoFixes++; labelFixesMade.Text = string.Format(" - {0}", _tesseractOcrAutoFixes); LogOcrFix(index, textWithOutFixes, line); } if (_vobSubMergedPackist != null) bitmap.Dispose(); return line; }
/// <summary> /// The make 3 d top bottom. /// </summary> /// <param name="parameter"> /// The parameter. /// </param> /// <param name="nbmp"> /// The nbmp. /// </param> /// <returns> /// The <see cref="NikseBitmap"/>. /// </returns> private static NikseBitmap Make3DTopBottom(MakeBitmapParameter parameter, NikseBitmap nbmp) { Bitmap singleBmp = nbmp.GetBitmap(); Bitmap singleHalfBmp = ScaleToHalfHeight(singleBmp); singleBmp.Dispose(); var 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; }
internal static void WriteTrack(string fileName, string outputFolder, bool overwrite, int count, StreamWriter stdOutWriter, CommandLineConverter.BatchConvertProgress progressCallback, Point?resolution, ProgramMapTableParser programMapTableParser, int pid, TransportStreamParser tsParser) { var overrideScreenSize = Configuration.Settings.Tools.BatchConvertTsOverrideScreenSize && Configuration.Settings.Tools.BatchConvertTsScreenHeight > 0 && Configuration.Settings.Tools.BatchConvertTsScreenWidth > 0 || resolution.HasValue; using (var form = new ExportPngXml()) { form.Initialize(new Subtitle(), new SubRip(), BatchConvert.BluRaySubtitle, fileName, null, fileName); var language = GetFileNameEnding(programMapTableParser, pid); var outputFileName = CommandLineConverter.FormatOutputFileNameForBatchConvert(Utilities.GetPathAndFileNameWithoutExtension(fileName) + language + Path.GetExtension(fileName), ".sup", outputFolder, overwrite); stdOutWriter?.Write($"{count}: {Path.GetFileName(fileName)} -> PID {pid} to {outputFileName}..."); var sub = tsParser.GetDvbSubtitles(pid); progressCallback?.Invoke($"Save PID {pid}"); var subtitleScreenSize = GetSubtitleScreenSize(sub, overrideScreenSize, resolution); using (var binarySubtitleFile = new FileStream(outputFileName, FileMode.Create)) { for (int index = 0; index < sub.Count; index++) { var p = sub[index]; var pos = p.GetPosition(); var bmp = sub[index].GetBitmap(); var tsWidth = bmp.Width; var tsHeight = bmp.Height; var nBmp = new NikseBitmap(bmp); pos.Top += nBmp.CropTopTransparent(0); pos.Left += nBmp.CropSidesAndBottom(0, Color.FromArgb(0, 0, 0, 0), true); bmp.Dispose(); bmp = nBmp.GetBitmap(); var mp = form.MakeMakeBitmapParameter(index, subtitleScreenSize.X, subtitleScreenSize.Y); if (overrideScreenSize) { var widthFactor = (double)subtitleScreenSize.X / tsWidth; var heightFactor = (double)subtitleScreenSize.Y / tsHeight; var resizeBmp = ResizeBitmap(bmp, (int)Math.Round(bmp.Width * widthFactor), (int)Math.Round(bmp.Height * heightFactor)); bmp.Dispose(); bmp = resizeBmp; pos.Left = (int)Math.Round(pos.Left * widthFactor); pos.Top = (int)Math.Round(pos.Top * heightFactor); progressCallback?.Invoke($"Save PID {pid}: {(index + 1) * 100 / sub.Count}%"); } mp.Bitmap = bmp; mp.P = new Paragraph(string.Empty, p.StartMilliseconds, p.EndMilliseconds); mp.ScreenWidth = subtitleScreenSize.X; mp.ScreenHeight = subtitleScreenSize.Y; if (Configuration.Settings.Tools.BatchConvertTsOverrideXPosition || Configuration.Settings.Tools.BatchConvertTsOverrideYPosition) { var overrideMarginX = (int)Math.Round(Configuration.Settings.Tools.BatchConvertTsOverrideHMargin * subtitleScreenSize.X / 100.0); var overrideMarginY = (int)Math.Round(Configuration.Settings.Tools.BatchConvertTsOverrideBottomMargin * subtitleScreenSize.Y / 100.0); if (Configuration.Settings.Tools.BatchConvertTsOverrideXPosition && Configuration.Settings.Tools.BatchConvertTsOverrideYPosition) { var x = (int)Math.Round(subtitleScreenSize.X / 2.0 - mp.Bitmap.Width / 2.0); if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("left", StringComparison.OrdinalIgnoreCase)) { x = overrideMarginX; } else if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("right", StringComparison.OrdinalIgnoreCase)) { x = subtitleScreenSize.X - overrideMarginX - mp.Bitmap.Width; } var y = subtitleScreenSize.Y - overrideMarginY - mp.Bitmap.Height; mp.OverridePosition = new Point(x, y); } else if (Configuration.Settings.Tools.BatchConvertTsOverrideXPosition) { var x = (int)Math.Round(subtitleScreenSize.X / 2.0 - mp.Bitmap.Width / 2.0); if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("left", StringComparison.OrdinalIgnoreCase)) { x = overrideMarginX; } else if (Configuration.Settings.Tools.BatchConvertTsOverrideHAlign.Equals("right", StringComparison.OrdinalIgnoreCase)) { x = subtitleScreenSize.X - overrideMarginX - mp.Bitmap.Width; } mp.OverridePosition = new Point(x, pos.Top); } else { var y = subtitleScreenSize.Y - overrideMarginY - mp.Bitmap.Height; mp.OverridePosition = new Point(pos.Left, y); } } else { mp.OverridePosition = new Point(pos.Left, pos.Top); // use original position (can be scaled) } ExportPngXml.MakeBluRaySupImage(mp); binarySubtitleFile.Write(mp.Buffer, 0, mp.Buffer.Length); mp.Bitmap?.Dispose(); mp.Bitmap = null; } } } stdOutWriter?.WriteLine(" done."); }
internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showExpand, bool showShrink, string text) { listBoxLinesForeground.Items.Clear(); listBoxlinesBackground.Items.Clear(); var nbmp = new NikseBitmap(vobSubImage); vobSubImage = nbmp.GetBitmap(); radioButtonHot.Checked = true; ShrinkSelection = false; ExpandSelection = false; textBoxCharacters.Text = text; NOcrChar = new NOcrChar { MarginTop = character.Top }; _imageWidth = character.NikseBitmap.Width; _imageHeight = character.NikseBitmap.Height; _drawLineOn = false; _warningNoNotForegroundLinesShown = false; buttonExpandSelection.Visible = showExpand; 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; numericUpDownLinesToDraw.Value = Configuration.Settings.VobSubOcr.LineOcrLinesToAutoGuess; GenerateLineSegments((int)numericUpDownLinesToDraw.Value, false, NOcrChar, new NikseBitmap(pictureBoxCharacter.Image as Bitmap)); ShowOcrPoints(); pictureBoxCharacter.Invalidate(); numericUpDownLinesToDraw.ValueChanged += (sender, args) => { Configuration.Settings.VobSubOcr.LineOcrLinesToAutoGuess = (int)numericUpDownLinesToDraw.Value; buttonGuessAgain_Click(null, null); }; textBoxCharacters.Focus(); }