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(); } }
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++; } }
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); }
internal static ImageSplitterItem GetExpandedSelectionNew(NikseBitmap bitmap, List<ImageSplitterItem> expandSelectionList) { int minimumX = expandSelectionList[0].X; int maximumX = expandSelectionList[expandSelectionList.Count - 1].X + expandSelectionList[expandSelectionList.Count - 1].NikseBitmap.Width; int minimumY = expandSelectionList[0].Y; int maximumY = expandSelectionList[0].Y + expandSelectionList[0].NikseBitmap.Height; var nbmp = new NikseBitmap(bitmap.Width, bitmap.Height); foreach (ImageSplitterItem item in expandSelectionList) { for (int y = 0; y < item.NikseBitmap.Height; y++) { for (int x = 0; x < item.NikseBitmap.Width; x++) { int a = item.NikseBitmap.GetAlpha(x, y); if (a > 100) nbmp.SetPixel(item.X + x, item.Y + y, Color.White); } } if (item.Y < minimumY) minimumY = item.Y; if (item.Y + item.NikseBitmap.Height > maximumY) maximumY = item.Y + item.NikseBitmap.Height; } nbmp.CropTransparentSidesAndBottom(0, true); int topCropping; nbmp = NikseBitmapImageSplitter.CropTopAndBottom(nbmp, out topCropping); return new ImageSplitterItem(minimumX, minimumY, nbmp); }
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 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()); }
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, 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 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(); } } }
/// <summary> /// The calc width via draw. /// </summary> /// <param name="text"> /// The text. /// </param> /// <param name="parameter"> /// The parameter. /// </param> /// <returns> /// The <see cref="int"/>. /// </returns> private static int CalcWidthViaDraw(string text, MakeBitmapParameter parameter) { // text = HtmlUtil.RemoveHtmlTags(text, true).Trim(); text = text.Trim(); var path = new GraphicsPath(); var sb = new StringBuilder(); int i = 0; bool isItalic = false; bool isBold = parameter.SubtitleFontBold; const float top = 5f; bool newLine = false; float left = 1.0f; float leftMargin = left; int newLinePathPoint = -1; Color c = parameter.SubtitleColor; var colorStack = new Stack<Color>(); var lastText = new StringBuilder(); var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Near }; var bmp = new Bitmap(parameter.ScreenWidth, 200); var g = Graphics.FromImage(bmp); g.CompositingQuality = CompositingQuality.HighSpeed; g.SmoothingMode = SmoothingMode.HighSpeed; g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; Font font = SetFont(parameter, parameter.SubtitleFontSize); 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) { 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(")) { 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 { sb.Append(text[i]); } i++; } if (sb.Length > 0) { TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); } DrawShadowAndPath(parameter, g, path); g.FillPath(new SolidBrush(c), path); g.Dispose(); var nbmp = new NikseBitmap(bmp); nbmp.CropTransparentSidesAndBottom(0, true); bmp.Dispose(); font.Dispose(); sf.Dispose(); return nbmp.Width; }
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(); }
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 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(); }