У меня есть два изображения, одно в качестве фона и одно с подписью.
Я хочу иметь возможность уменьшить / увеличить масштаб подписи в зависимости от коэффициента масштабирования, но в пределах высоты / ширины фона.
Я пробовал AffineTransformBuilder.AppendScale без какого-либо успеха, поэтому вместо этого я попытался масштабировать подпись с изменением размера.
Как я могу масштабировать изображение подписи в пределах фонового изображения?
Результаты изображения
Ожидаемый результат
Фактический результат с изменением размера
код
public class ImageConverter
{
public byte[] GetPngImage(byte[] plots)
{
var desiredWidth = 250;
var desiredHeight = 250;
var Rgba32 backgroundColor = Rgba32.White;
var Rgba32 foregroundColor = Rgba32.Black;
var plottedLines = GetPlottedLines(plots);
var minX = lines.Min(p => p.Start.X > p.End.X ? p.Start.X : p.End.X);
var maxX = lines.Max(p => p.Start.X > p.End.X ? p.Start.X : p.End.X);
var minY = lines.Min(p => p.Start.Y > p.End.Y ? p.Start.Y : p.End.Y);
var maxY = lines.Max(p => p.Start.Y > p.End.Y ? p.Start.Y : p.End.Y);
var width = maxX - minX;
var height = maxY - minY;
var scaleFactor = CalculateScaleFactor(width, height, desiredWidth, desiredHeight);
using (var canvas = new Image<Rgba32>(desiredWidth, desiredHeight))
using(var signature = new Image<Rgba32>(width, height))
{
signature.Mutate(ctx =>
{
var pen = new Pen<Rgba32>(foregroundColor, 1);
foreach (var line in plottedLines)
{
ctx.DrawLines(pen, new PointF(line.Start.X - minX, line.Start.Y - minY),
new PointF(line.End.X - minX, line.End.Y - minY));
}
ctx.Resize(new ResizeOptions
{
Size = new Size(desiredWidth, desiredHeight),
Mode = ResizeMode.BoxPad,
});
//var transformX = ((desiredWidth / 2f) - (width * scaleFactor) / 2f) < 0f ? 0f : ((desiredWidth / 2f) - (width * scaleFactor) / 2f);
//var transformY = ((desiredHeight / 2f) - (height * scaleFactor) / 2f) < 0f ? 0f : ((desiredHeight / 2f) - (height * scaleFactor) / 2f);
//var transformBuilder = new AffineTransformBuilder();
//transformBuilder.AppendTranslation(new PointF(transformX, transformY));
//transformBuilder.AppendScale(scaleFactor);
//ctx.Transform(transformBuilder);
//var pen = new Pen<Rgba32>(foregroundColor, 1);
//foreach (var line in plottedLines)
//{
//ctx.DrawLines(pen, new PointF(line.Start.X - minX, line.Start.Y - minY), new PointF(line.End.X - minX, line.End.Y - minY));
//}
});
canvas.Mutate(ctx =>
{
ctx.Fill(new SolidBrush<Rgba32>(backgroundColor), new RectangleF(0, 0, desiredWidth, desiredHeight));
ctx.DrawImage(signature, new Point(0, 0), 1);
});
using (var ms = new MemoryStream())
{
canvas.Save(ms, new PngEncoder());
return ms.ToArray();
}
}
}
private List<Line> GetPlottedLines(byte[] plotChunk)
{
var plotString = Encoding.Default.GetString(plotChunk);
var lines = plotString.Split(new[] {"|"}, StringSplitOptions.RemoveEmptyEntries);
return lines.Select(line =>
line.Split(new[] {","}, StringSplitOptions.RemoveEmptyEntries))
.Select(points => new Line(
new Point(Convert.ToInt32(points[0]), Convert.ToInt32(points[1])),
new Point(Convert.ToInt32(points[2]), Convert.ToInt32(points[3]))))
.ToList();
}
private float CalculateScaleFactor(float currentImageWidthInPixels, float currentImageHeightInPixels,
int desiredWidthInPixels, int desiredHeightInPixels)
{
var scaleFactorWidth = desiredWidthInPixels / currentImageWidthInPixels;
var scaleFactorHeight = desiredHeightInPixels / currentImageHeightInPixels;
var scaleFactor = scaleFactorWidth < scaleFactorHeight ? scaleFactorWidth : scaleFactorHeight;
return scaleFactor == 0.0 ? 1.0f : scaleFactor;
}
private class Line
{
internal Point Start { get; }
internal Point End { get; }
public Line(Point start, Point end)
{
Start = start;
End = end;
}
}
}