cross-posting this from the ImageSharp.Drawing GitHub discussion since it's still unanswered after 3 weeks
I'm trying to replicate this:
With this code:
public void Draw(string text)
{
var imageSize = 300;
var fontSize = 18;
var border = 10;
var color = Color.ParseHex("#808080");
FontFamily family = SystemFonts.Get("Arial");
Font font = new(family, fontSize);
var radius = imageSize / 2;
var center = new PointF(radius, radius);
var img = Image<Rgba32>.Load(@"C:\Users\sergi\Downloads\comet.png");
img.Mutate(o => o.Resize(new Size(imageSize, imageSize)));
var topSegment = new ArcLineSegment(center, new SizeF(radius-border, radius-border), 0, -220, 260);
PathBuilder pathBuilder = new PathBuilder();
pathBuilder.AddSegment(topSegment);
var textSegment = new ArcLineSegment(center, new SizeF(radius- fontSize/2 - border, radius- fontSize/2-border), 0, -220, -100);
IPath textShape = new Polygon(textSegment);
TextOptions textOptions = new(font)
{
WrappingLength = textShape.ComputeLength(),
VerticalAlignment = VerticalAlignment.Top,
HorizontalAlignment = HorizontalAlignment.Left,
TextAlignment = TextAlignment.Center,
TextDirection = TextDirection.LeftToRight
};
DrawingOptions options = new()
{
GraphicsOptions = new()
{
ColorBlendingMode = PixelColorBlendingMode.Multiply
}
};
IPen pen = Pens.Solid(color, 1);
img.Mutate(x => x.Draw(color, 2, pathBuilder.Build()));
img.Mutate(x => x.Draw(color, 2, new PathBuilder().AddSegment(textSegment).Build()));
IPathCollection glyphs = TextBuilder.GenerateGlyphs(text, textShape, textOptions);
img.Mutate(i => i.Fill(color, glyphs));
string fullPath = IOPath.GetFullPath(IOPath.Combine("Output", IOPath.Combine(
"test.png")));
IODirectory.CreateDirectory(IOPath.GetDirectoryName(fullPath));
img.Save(fullPath);
Console.WriteLine($"Saved to {fullPath}");
}
I get to this result:
How do I make the text use the whole space so that the center alignment will actually put the text in the center of the arc?
I experimented with different segments, I have the same issue with a simpler line segment:
var textSegment = new LinearLineSegment(new PointF(50, 150), new PointF(250, 150));
IPath textShape = new Polygon(textSegment);
TextOptions textOptions = new(font)
{
//WrappingLength = textShape.ComputeLength(),
VerticalAlignment = VerticalAlignment.Top,
HorizontalAlignment = HorizontalAlignment.Center,
TextAlignment = TextAlignment.Center,
};
Similarly TextAligment
has no effect and having HorizontalAligment.Center
will cause the text to be aligned in the middle of the segment start point:
test
What is also strange is that the textShape.ComputeLength()
returns 400 in the above example, whereas the segment is only 200 long.
Thanks a lot