public TextSubtitle() { Style = new SubtitleStyle(); Captions = new List<SubCaption>(); }
public static ImageHolder CreateImage(SubCaption caption, SubtitleStyle style, int number, int videoWidth, int videoHeight, string baseFName) { _boldStyle = false; _italicStyle = false; _underlineStyle = false; _strikeStyle = false; ImageHolder result = new ImageHolder(); if (string.IsNullOrEmpty(baseFName)) { return(new ImageHolder()); } string basePath = Path.GetDirectoryName(baseFName); string baseName = Path.GetFileNameWithoutExtension(baseFName); if (string.IsNullOrEmpty(basePath) || string.IsNullOrEmpty(baseName)) { return(new ImageHolder()); } result.FileName = string.Format(AppSettings.CInfo, "{0}_{1:g}.png", Path.Combine(basePath, baseName), number); SizeF imgSize = new SizeF(); FontStyle styleFontStyle = FontStyle.Regular; if (style.Bold) { styleFontStyle = styleFontStyle | FontStyle.Bold; } if (style.Italic) { styleFontStyle = styleFontStyle | FontStyle.Italic; } Font styleFont = new Font(style.FontName, style.FontSize, styleFontStyle, GraphicsUnit.Point); StringFormat stringFormat = new StringFormat(); List <SizeF> lineSizes = new List <SizeF>(); string rawText = Regex.Replace(caption.Text, "</*?(?:i|b)>", "", RegexOptions.Singleline | RegexOptions.Multiline); string[] rawTextLines = rawText.Split(new[] { Environment.NewLine }, StringSplitOptions.None); foreach (string rawTextLine in rawTextLines) { using (GraphicsPath rawLinePath = new GraphicsPath()) { rawLinePath.AddString(rawTextLine, styleFont.FontFamily, (int)styleFontStyle, styleFont.SizeInPoints, new PointF(), stringFormat); lineSizes.Add(rawLinePath.GetBounds().Size); } } string[] textLines = caption.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None); float lastLineBreak = 0f; foreach (SizeF lineSize in lineSizes) { imgSize.Height += lineSize.Height; lastLineBreak = lineSize.Height / 3; imgSize.Height += lastLineBreak; if (lineSize.Width > imgSize.Width) { imgSize.Width = lineSize.Width; } } imgSize.Height -= lastLineBreak; if (imgSize.IsEmpty) { return(new ImageHolder()); } stringFormat.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, 1) }); RectangleF whiteSpace; using (Image img = new Bitmap((int)imgSize.Width, (int)imgSize.Height, PixelFormat.Format32bppArgb)) { using (Graphics g = Graphics.FromImage(img)) { RectangleF origin = new RectangleF(new PointF(0f, 0f), imgSize); Region[] regions2 = g.MeasureCharacterRanges(" .", styleFont, origin, stringFormat); if (!regions2.Any()) { return(new ImageHolder()); } whiteSpace = regions2[0].GetBounds(g); } } GraphicsPath wordpath = new GraphicsPath(); GraphicsPath wordPathShadow = new GraphicsPath(); int shadowOffset = style.Shadow; RectangleF wStart = new RectangleF { Y = 0, X = 0 }; RectangleF wStartShadow = wStart; wStartShadow.Offset(shadowOffset, shadowOffset); for (int i = 0; i < textLines.Length; i++) { string textLine = textLines[i]; SizeF lineSize = lineSizes[i]; wStart.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); wStartShadow.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); string[] words = textLine.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); foreach (string word in words) { using (GraphicsPath singleWord = new GraphicsPath(), singleWordShadow = new GraphicsPath()) { string lWord; FontStyle fontStyle = GetStyleFont(word, out lWord, styleFontStyle); if (string.IsNullOrEmpty(lWord)) { continue; } singleWord.AddString(lWord, styleFont.FontFamily, (int)fontStyle, styleFont.SizeInPoints, wStart.Location, stringFormat); singleWordShadow.AddString(lWord, styleFont.FontFamily, (int)fontStyle, styleFont.SizeInPoints, wStartShadow.Location, stringFormat); wordpath.AddPath(singleWord, false); wordPathShadow.AddPath(singleWordShadow, false); wStart.Offset(singleWord.GetBounds().Size.Width + whiteSpace.Size.Width, 0); wStartShadow.Offset(singleWordShadow.GetBounds().Size.Width + whiteSpace.Size.Width, 0); } } wStart.X = 0; wStart.Offset(0, lineSize.Height + lineSize.Height / 3); wStartShadow.X = shadowOffset; wStartShadow.Offset(0, lineSize.Height + lineSize.Height / 3); } imgSize.Width = wordPathShadow.GetBounds().Right; imgSize.Height = wordPathShadow.GetBounds().Bottom; using (Image img = new Bitmap((int)imgSize.Width + style.MarginL + style.MarginR, (int)imgSize.Height + style.MarginV * 2, PixelFormat.Format32bppArgb)) { using (Graphics g = Graphics.FromImage(img)) { g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAlias; g.SmoothingMode = SmoothingMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.InterpolationMode = InterpolationMode.High; Brush primBrush = new SolidBrush(style.PrimaryColor); Brush shadowBrush = new SolidBrush(Color.FromArgb(64, style.BackColor)); Pen outPen = new Pen(style.OutlineColor) { Alignment = PenAlignment.Outset }; if (style.BorderStyle == 1) { outPen.Width = style.Outline == 0 && style.Shadow > 0 ? 1 : style.Outline; style.Outline = (int)outPen.Width; } g.FillRectangle(Brushes.Transparent, 0, 0, img.Width, img.Height); // draw shadow if (style.BorderStyle == 1 && style.Shadow > 0) { g.FillPath(shadowBrush, wordPathShadow); } g.FillPath(primBrush, wordpath); // draw outline if (style.BorderStyle == 1 && style.Outline > 0) { g.DrawPath(outPen, wordpath); } } img.Save(result.FileName, ImageFormat.Png); result.FileName = Path.GetFileName(result.FileName); result.Height = img.Height; result.Width = img.Width; } return(result); }
public TextSubtitle() { Style = new SubtitleStyle(); Captions = new List <SubCaption>(); }
public static ImageHolder CreateImage(SubCaption caption, SubtitleStyle style, int number, int videoWidth, int videoHeight, string baseFName) { _boldStyle = false; _italicStyle = false; _underlineStyle = false; _strikeStyle = false; ImageHolder result = new ImageHolder(); if (string.IsNullOrEmpty(baseFName)) return new ImageHolder(); string basePath = Path.GetDirectoryName(baseFName); string baseName = Path.GetFileNameWithoutExtension(baseFName); if (string.IsNullOrEmpty(basePath) || string.IsNullOrEmpty(baseName)) return new ImageHolder(); result.FileName = string.Format(AppSettings.CInfo, "{0}_{1:g}.png", Path.Combine(basePath, baseName), number); SizeF imgSize = new SizeF(); FontStyle styleFontStyle = FontStyle.Regular; if (style.Bold) styleFontStyle = styleFontStyle | FontStyle.Bold; if (style.Italic) styleFontStyle = styleFontStyle | FontStyle.Italic; Font styleFont = new Font(style.FontName, style.FontSize, styleFontStyle, GraphicsUnit.Point); StringFormat stringFormat = new StringFormat(); List<SizeF> lineSizes = new List<SizeF>(); string rawText = Regex.Replace(caption.Text, "</*?(?:i|b)>", "", RegexOptions.Singleline | RegexOptions.Multiline); string[] rawTextLines = rawText.Split(new[] {Environment.NewLine}, StringSplitOptions.None); foreach (string rawTextLine in rawTextLines) { using (GraphicsPath rawLinePath = new GraphicsPath()) { rawLinePath.AddString(rawTextLine, styleFont.FontFamily, (int) styleFontStyle, styleFont.SizeInPoints, new PointF(), stringFormat); lineSizes.Add(rawLinePath.GetBounds().Size); } } string[] textLines = caption.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None); float lastLineBreak = 0f; foreach (SizeF lineSize in lineSizes) { imgSize.Height += lineSize.Height; lastLineBreak = lineSize.Height/3; imgSize.Height += lastLineBreak; if (lineSize.Width > imgSize.Width) imgSize.Width = lineSize.Width; } imgSize.Height -= lastLineBreak; if (imgSize.IsEmpty) return new ImageHolder(); stringFormat.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, 1) }); RectangleF whiteSpace; using (Image img = new Bitmap((int)imgSize.Width, (int)imgSize.Height, PixelFormat.Format32bppArgb)) { using (Graphics g = Graphics.FromImage(img)) { RectangleF origin = new RectangleF(new PointF(0f,0f), imgSize); Region[] regions2 = g.MeasureCharacterRanges(" .", styleFont, origin, stringFormat); if (!regions2.Any()) return new ImageHolder(); whiteSpace = regions2[0].GetBounds(g); } } GraphicsPath wordpath = new GraphicsPath(); GraphicsPath wordPathShadow = new GraphicsPath(); int shadowOffset = style.Shadow; RectangleF wStart = new RectangleF { Y = 0, X = 0 }; RectangleF wStartShadow = wStart; wStartShadow.Offset(shadowOffset, shadowOffset); for (int i = 0; i < textLines.Length; i++) { string textLine = textLines[i]; SizeF lineSize = lineSizes[i]; wStart.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); wStartShadow.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); string[] words = textLine.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); foreach (string word in words) { using (GraphicsPath singleWord = new GraphicsPath(), singleWordShadow = new GraphicsPath()) { string lWord; FontStyle fontStyle = GetStyleFont(word, out lWord, styleFontStyle); if (string.IsNullOrEmpty(lWord)) continue; singleWord.AddString(lWord, styleFont.FontFamily, (int) fontStyle, styleFont.SizeInPoints, wStart.Location, stringFormat); singleWordShadow.AddString(lWord, styleFont.FontFamily, (int) fontStyle, styleFont.SizeInPoints, wStartShadow.Location, stringFormat); wordpath.AddPath(singleWord, false); wordPathShadow.AddPath(singleWordShadow, false); wStart.Offset(singleWord.GetBounds().Size.Width + whiteSpace.Size.Width, 0); wStartShadow.Offset(singleWordShadow.GetBounds().Size.Width + whiteSpace.Size.Width, 0); } } wStart.X = 0; wStart.Offset(0, lineSize.Height + lineSize.Height / 3); wStartShadow.X = shadowOffset; wStartShadow.Offset(0, lineSize.Height + lineSize.Height / 3); } imgSize.Width = wordPathShadow.GetBounds().Right; imgSize.Height = wordPathShadow.GetBounds().Bottom; using (Image img = new Bitmap((int)imgSize.Width + style.MarginL + style.MarginR, (int)imgSize.Height + style.MarginV * 2, PixelFormat.Format32bppArgb)) { using (Graphics g = Graphics.FromImage(img)) { g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAlias; g.SmoothingMode = SmoothingMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.InterpolationMode = InterpolationMode.High; Brush primBrush = new SolidBrush(style.PrimaryColor); Brush shadowBrush = new SolidBrush(Color.FromArgb(64, style.BackColor)); Pen outPen = new Pen(style.OutlineColor) {Alignment = PenAlignment.Outset}; if (style.BorderStyle == 1) { outPen.Width = style.Outline == 0 && style.Shadow > 0 ? 1 : style.Outline; style.Outline = (int) outPen.Width; } g.FillRectangle(Brushes.Transparent, 0, 0, img.Width, img.Height); // draw shadow if (style.BorderStyle == 1 && style.Shadow > 0) g.FillPath(shadowBrush, wordPathShadow); g.FillPath(primBrush, wordpath); // draw outline if (style.BorderStyle == 1 && style.Outline > 0) g.DrawPath(outPen, wordpath); } img.Save(result.FileName, ImageFormat.Png); result.FileName = Path.GetFileName(result.FileName); result.Height = img.Height; result.Width = img.Width; } return result; }