108 lines
4.0 KiB
C#
108 lines
4.0 KiB
C#
using System;
|
|
using SixLabors.Fonts;
|
|
using SixLabors.ImageSharp;
|
|
using SixLabors.ImageSharp.Drawing.Processing;
|
|
using SixLabors.ImageSharp.Processing;
|
|
|
|
namespace ImageProvider.Extensions {
|
|
internal static class IImageProcessingContextExtensions {
|
|
internal static IImageProcessingContext ApplyScalingWaterMark(this IImageProcessingContext processingContext, Font font, string text, Color color, float padding, bool wordwrap) {
|
|
if (wordwrap) {
|
|
return processingContext.ApplyScalingWaterMarkWordWrap(font, text, color, padding);
|
|
}
|
|
else {
|
|
return processingContext.ApplyScalingWaterMarkSimple(font, text, color, padding);
|
|
}
|
|
}
|
|
|
|
internal static IImageProcessingContext ApplyScalingWaterMarkSimple(this IImageProcessingContext processingContext,
|
|
Font font,
|
|
string text,
|
|
Color color,
|
|
float padding) {
|
|
Size imgSize = processingContext.GetCurrentSize();
|
|
|
|
float targetWidth = imgSize.Width - (padding * 2);
|
|
float targetHeight = imgSize.Height - (padding * 2);
|
|
|
|
// measure the text size
|
|
FontRectangle 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(imgSize.Width / size.Width, imgSize.Height / size.Height);
|
|
|
|
//create a new font
|
|
Font scaledFont = new Font(font, scalingFactor * font.Size);
|
|
|
|
var center = new PointF(imgSize.Width / 2, imgSize.Height / 2);
|
|
var textGraphicOptions = new TextGraphicsOptions() {
|
|
TextOptions = {
|
|
HorizontalAlignment = HorizontalAlignment.Center,
|
|
VerticalAlignment = VerticalAlignment.Center
|
|
}
|
|
};
|
|
return processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center);
|
|
}
|
|
|
|
internal static IImageProcessingContext ApplyScalingWaterMarkWordWrap(this IImageProcessingContext processingContext,
|
|
Font font,
|
|
string text,
|
|
Color color,
|
|
float padding) {
|
|
Size imgSize = processingContext.GetCurrentSize();
|
|
float targetWidth = imgSize.Width - (padding * 2);
|
|
float targetHeight = imgSize.Height - (padding * 2);
|
|
|
|
float targetMinHeight = imgSize.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;
|
|
FontRectangle s = new FontRectangle(0, 0, float.MaxValue, float.MaxValue);
|
|
|
|
float scaleFactor = (scaledFont.Size / 2); // every time 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, imgSize.Height / 2);
|
|
var textGraphicOptions = new TextGraphicsOptions() {
|
|
TextOptions = {
|
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|
VerticalAlignment = VerticalAlignment.Center,
|
|
WrapTextWidth = targetWidth
|
|
}
|
|
};
|
|
return processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center);
|
|
}
|
|
}
|
|
}
|