-
Notifications
You must be signed in to change notification settings - Fork 56
/
Program.cs
157 lines (133 loc) · 6.68 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing.Drawing;
using SixLabors.ImageSharp.Processing.Drawing.Brushes;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.Primitives;
using SixLabors.Shapes;
using SixLabors.ImageSharp.Processing.Text;
namespace AvatarWithRoundedCorner
{
static class Program
{
static void Main(string[] args)
{
System.IO.Directory.CreateDirectory("output");
using (Image<Rgba32> img = new Image<Rgba32>(1500, 500))
{
PathBuilder pathBuilder = new PathBuilder();
pathBuilder.SetOrigin(new PointF(500, 0));
pathBuilder.AddBezier(new PointF(50, 450), new PointF(200, 50), new PointF(300, 50), new PointF(450, 450));
// add more complex paths and shapes here.
IPath path = pathBuilder.Build();
// For production application we would recomend you create a FontCollection
// singleton and manually install the ttf fonts yourself as using SystemFonts
// can be expensive and you risk font existing or not existing on a deployment
// by deployment basis.
var font = SystemFonts.CreateFont("Arial", 39, FontStyle.Regular);
string text = "Hello World Hello World Hello World Hello World Hello World";
var textGraphicsOptions = new TextGraphicsOptions(true) // draw the text along the path wrapping at the end of the line
{
WrapTextWidth = path.Length
};
img.Mutate(ctx => ctx
.Fill(Rgba32.White) // white background image
.Draw(Rgba32.Gray, 3, path) // draw the path so we can see what the text is supposed to be following
.DrawText(textGraphicsOptions, text, font, Rgba32.Black, path));
img.Save("output/wordart.png");
}
}
public static IImageProcessingContext<TPixel> ApplyScalingWaterMark<TPixel>(this IImageProcessingContext<TPixel> processingContext, Font font, string text, TPixel color, float padding, bool wordwrap)
where TPixel : struct, IPixel<TPixel>
{
if (wordwrap)
{
return processingContext.ApplyScalingWaterMarkWordWrap(font, text, color, padding);
}
else
{
return processingContext.ApplyScalingWaterMarkSimple(font, text, color, padding);
}
}
public static IImageProcessingContext<TPixel> ApplyScalingWaterMarkSimple<TPixel>(this IImageProcessingContext<TPixel> processingContext, Font font, string text, TPixel color, float padding)
where TPixel : struct, IPixel<TPixel>
{
return processingContext.Apply(img =>
{
float targetWidth = img.Width - (padding * 2);
float targetHeight = img.Height - (padding * 2);
// measure the text size
SizeF size = TextMeasurer.Measure(text, new RendererOptions(font));
//find out how much we need to scale the text to fill the space (up or down)
float scalingFactor = Math.Min(img.Width / size.Width, img.Height / size.Height);
//create a new font
Font scaledFont = new Font(font, scalingFactor * font.Size);
var center = new PointF(img.Width / 2, img.Height / 2);
var textGraphicsOptions = new TextGraphicsOptions(true) {
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
img.Mutate(i => i.DrawText(textGraphicsOptions, text, scaledFont, color, center));
});
}
public static IImageProcessingContext<TPixel> ApplyScalingWaterMarkWordWrap<TPixel>(this IImageProcessingContext<TPixel> processingContext, Font font, string text, TPixel color, float padding)
where TPixel : struct, IPixel<TPixel>
{
return processingContext.Apply(img =>
{
float targetWidth = img.Width - (padding * 2);
float targetHeight = img.Height - (padding * 2);
float targetMinHeight = img.Height - (padding * 3); // must be with in a margin width of the target height
// now we are working i 2 dimensions at once and can't just scale because it will cause the text to
// reflow we need to just try multiple times
var scaledFont = font;
SizeF s = new SizeF(float.MaxValue, float.MaxValue);
float scaleFactor = (scaledFont.Size / 2);// everytime we change direction we half this size
int trapCount = (int)scaledFont.Size * 2;
if (trapCount < 10)
{
trapCount = 10;
}
bool isTooSmall = false;
while ((s.Height > targetHeight || s.Height < targetMinHeight) && trapCount > 0)
{
if (s.Height > targetHeight)
{
if (isTooSmall)
{
scaleFactor = scaleFactor / 2;
}
scaledFont = new Font(scaledFont, scaledFont.Size - scaleFactor);
isTooSmall = false;
}
if (s.Height < targetMinHeight)
{
if (!isTooSmall)
{
scaleFactor = scaleFactor / 2;
}
scaledFont = new Font(scaledFont, scaledFont.Size + scaleFactor);
isTooSmall = true;
}
trapCount--;
s = TextMeasurer.Measure(text, new RendererOptions(scaledFont)
{
WrappingWidth = targetWidth
});
}
var center = new PointF(padding, img.Height / 2);
var textGraphicsOptions = new TextGraphicsOptions(true) {
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
WrapTextWidth = targetWidth
};
img.Mutate(i => i.DrawText(textGraphicsOptions, text, scaledFont, color, center));
});
}
}
}