C# 在现有图像文件上写入文本?
所以我在WinForms.NET3.5中做这个。。。我现在正在使用WPF.NET4.0。。。我不知道该怎么做 这就是我在Windows.NET3.5中所做的C# 在现有图像文件上写入文本?,c#,.net,wpf,visual-studio,C#,.net,Wpf,Visual Studio,所以我在WinForms.NET3.5中做这个。。。我现在正在使用WPF.NET4.0。。。我不知道该怎么做 这就是我在Windows.NET3.5中所做的 using (Bitmap eventImg = new Bitmap("input.png")) { Graphics eventGfx = Graphics.FromImage(eventImg); buildText(eventGfx, this.event1.Text); eventImg.Save("o
using (Bitmap eventImg = new Bitmap("input.png"))
{
Graphics eventGfx = Graphics.FromImage(eventImg);
buildText(eventGfx, this.event1.Text);
eventImg.Save("output.png", ImageFormat.Png);
eventGfx.Dispose();
}
上面的代码在“input.png”中获取现有图像,从中创建新图像,从中写入文本,然后将新图像保存在“output.png”中。使用以下函数编写文本:
private void buildText(Graphics graphic, string text)
{
if (text.Length == 0) { return; }
FontStyle weight = FontStyle.Regular;
switch (this.font_style)
{
case "regular": weight = FontStyle.Regular; break;
case "bold": weight = FontStyle.Bold; break;
case "italic": weight = FontStyle.Italic; break;
case "underline": weight = FontStyle.Underline; break;
case "strikeout": weight = FontStyle.Strikeout; break;
}
using (Font font = new Font(this.font_family, this.font_size, weight, GraphicsUnit.Pixel))
{
Rectangle rect = new Rectangle(this.left, this.top, this.width, this.height);
Brush brush = new SolidBrush(Color.FromArgb(this.font_color));
StringFormat format = new StringFormat();
switch (this.align_x)
{
case "left": format.Alignment = StringAlignment.Near; break;
case "right": format.Alignment = StringAlignment.Far; break;
default: format.Alignment = StringAlignment.Center; break;
}
switch (this.align_y)
{
case "top": format.LineAlignment = StringAlignment.Near; break;
case "bottom": format.LineAlignment = StringAlignment.Far; break;
default: format.LineAlignment = StringAlignment.Center; break;
}
graphic.TextRenderingHint = TextRenderingHint.AntiAlias;
graphic.DrawString(text, font, brush, rect, format);
}
}
然而,由于System.Drawing在WPF.NET4.0中不存在,我不能再使用这些函数了。我将如何做我在WPF.NET4.0中尝试做的事情?为了完成基于旧图像制作图像的第一步,我已经完成了以下代码:
using (var fileStream = new FileStream(@"z:\ouput.png", FileMode.Create))
{
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(new Uri(@"z:\input.png")));
encoder.Save(fileStream);
}
在WPF中,不允许使用图形,因为WPF提供了新的tec。这样做。 图形引用旧的Windows API,但WPF使用DirectX。例如,WPF不再适用于像素等
阅读了这里的答案和评论后,我想您可能会喜欢一个更全面的解决方案。这里有一个小方法可以完成这项工作:
public static void WriteTextToImage(string inputFile, string outputFile, FormattedText text, Point position)
{
BitmapImage bitmap = new BitmapImage(new Uri(inputFile)); // inputFile must be absolute path
DrawingVisual visual = new DrawingVisual();
using (DrawingContext dc = visual.RenderOpen())
{
dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
dc.DrawText(text, position);
}
RenderTargetBitmap target = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight,
bitmap.DpiX, bitmap.DpiY, PixelFormats.Default);
target.Render(visual);
BitmapEncoder encoder = null;
switch (Path.GetExtension(outputFile))
{
case ".png":
encoder = new PngBitmapEncoder();
break;
// more encoders here
}
if (encoder != null)
{
encoder.Frames.Add(BitmapFrame.Create(target));
using (FileStream outputStream = new FileStream(outputFile, FileMode.Create))
{
encoder.Save(outputStream);
}
}
}
您可以将此方法用于对象和位置:
FormattedText text = new FormattedText(
"Hello",
CultureInfo.InvariantCulture,
FlowDirection.LeftToRight,
new Typeface("Segeo UI"),
20,
Brushes.Red);
WriteTextToImage(
@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg",
"Desert.png",
text,
new Point(10, 10));
编辑:如果要绘制相对于某个矩形水平和垂直对齐的文本,可以将位置
参数替换为该矩形和两个对齐参数,并按如下方式计算文本位置:
public static void WriteTextToImage(string inputFile, string outputFile, FormattedText text,
Rect textRect, HorizontalAlignment hAlign, VerticalAlignment vAlign)
{
BitmapImage bitmap = new BitmapImage(new Uri(inputFile));
DrawingVisual visual = new DrawingVisual();
Point position = textRect.Location;
switch (hAlign)
{
case HorizontalAlignment.Center:
position.X += (textRect.Width - text.Width) / 2;
break;
case HorizontalAlignment.Right:
position.X += textRect.Width - text.Width;
break;
}
switch (vAlign)
{
case VerticalAlignment.Center:
position.Y += (textRect.Height - text.Height) / 2;
break;
case VerticalAlignment.Bottom:
position.Y += textRect.Height - text.Height;
break;
}
using (DrawingContext dc = visual.RenderOpen())
{
dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
dc.DrawText(text, position);
}
RenderTargetBitmap target = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight,
bitmap.DpiX, bitmap.DpiY, PixelFormats.Default);
target.Render(visual);
BitmapEncoder encoder = null;
switch (Path.GetExtension(outputFile))
{
case ".png":
encoder = new PngBitmapEncoder();
break;
case ".jpg":
encoder = new JpegBitmapEncoder();
break;
}
if (encoder != null)
{
encoder.Frames.Add(BitmapFrame.Create(target));
using (FileStream outputStream = new FileStream(outputFile, FileMode.Create))
{
encoder.Save(outputStream);
}
}
}
WriteTextToImage(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg", "Desert.png", text,
new Rect(80, 50, 430, 200),
HorizontalAlignment.Center, VerticalAlignment.Center);
现在您可以使用如下方法:
public static void WriteTextToImage(string inputFile, string outputFile, FormattedText text,
Rect textRect, HorizontalAlignment hAlign, VerticalAlignment vAlign)
{
BitmapImage bitmap = new BitmapImage(new Uri(inputFile));
DrawingVisual visual = new DrawingVisual();
Point position = textRect.Location;
switch (hAlign)
{
case HorizontalAlignment.Center:
position.X += (textRect.Width - text.Width) / 2;
break;
case HorizontalAlignment.Right:
position.X += textRect.Width - text.Width;
break;
}
switch (vAlign)
{
case VerticalAlignment.Center:
position.Y += (textRect.Height - text.Height) / 2;
break;
case VerticalAlignment.Bottom:
position.Y += textRect.Height - text.Height;
break;
}
using (DrawingContext dc = visual.RenderOpen())
{
dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
dc.DrawText(text, position);
}
RenderTargetBitmap target = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight,
bitmap.DpiX, bitmap.DpiY, PixelFormats.Default);
target.Render(visual);
BitmapEncoder encoder = null;
switch (Path.GetExtension(outputFile))
{
case ".png":
encoder = new PngBitmapEncoder();
break;
case ".jpg":
encoder = new JpegBitmapEncoder();
break;
}
if (encoder != null)
{
encoder.Frames.Add(BitmapFrame.Create(target));
using (FileStream outputStream = new FileStream(outputFile, FileMode.Create))
{
encoder.Save(outputStream);
}
}
}
WriteTextToImage(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg", "Desert.png", text,
new Rect(80, 50, 430, 200),
HorizontalAlignment.Center, VerticalAlignment.Center);
您可以按以下方式使用网格或任何其他适合您需要的面板
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image x:name="My image" .. bind it to the bintmap
Grid.row="0"
Grid.colomn="0"/>
<TextBlock x:name="MyText"
Text="....."
Grid.row="0"
Grid.colomn="0"/>
</Grid>
文本和图像在网格中的同一空间中绘制,您可以根据Silverlight中的相同内容随意操纵对齐方式,您可以将位图加载到一个图像元素中,该图像元素上只包含一个文本元素,然后将父容器渲染为可写位图并保存该位图。HiTech,你能详细解释一下怎么做吗?这是我第一次使用WPF。好吧,这正是我想要的。。。然而,有一个根本问题。DrawText将文本放置在具有新点(x,y)的特定x,y坐标处。问题是,有时我的文本集中在一个矩形区域内。有没有办法将文本绘制到一个矩形区域,然后用垂直对齐和水平对齐对齐文本?@JasonAxelrod计算对齐文本的位置非常简单,因为您知道图像的大小和文本的大小。看我编辑的答案。我不知道,数学对我来说没有意义。。。好的,假设图像宽度是
1280
;我想将文本对齐在一个矩形区域中,从80
(存储在一个名为left
的变量中)的像素开始。矩形区域的宽度为430
(存储在名为width
的变量中)像素。我该如何计算使文本中心在矩形区域内对齐。。。对吗?我绞尽脑汁想弄清楚数学。。。但这对我来说毫无意义。你不认为是时候自己做一些研究了吗?有大量关于WPF的文档。请参阅关于em
size。