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() { 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(); }
/// <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; } }
/// <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; }
/// <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(); } } }
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 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); } }
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); }
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); }