ImageSharp:绘制超出边界的裁剪多边形
ImageSharp: Drawing a clipped Polygon out of bounds
我目前正在将一个使用 System.Drawing.Bitmap
的项目迁移到使用 ImageSharp。作为此迁移的一部分,我正在迁移使用 Graphics.FromImage
函数在位图上绘制圆圈的逻辑。
我面临的问题是,如果圆圈之前超出了位图的边界,这在以前是没问题的,它会绘制圆圈的部分,只需剪裁绘制的圆圈即可。使用 ImageSharp,可以理解,这会抛出越界异常。
简化的实现:
void Main()
{
var width = 70;
var height = 70;
SystemDrawingImpl(width, height);
ImageSharpImpl(width, height);
}
private void SystemDrawingImpl(int width, int height)
{
using var bitmap = new Bitmap(64, 64);
using var graphics = Graphics.FromImage(bitmap);
var xLocation = ((bitmap.Width / 2) - (width / 2)) - 1;
var yLocation = ((bitmap.Height / 2) - (height / 2)) - 1;
graphics.DrawEllipse(new System.Drawing.Pen(System.Drawing.Color.Green, 1.1f), xLocation, yLocation, width, height);
var memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Jpeg);
Util.Image(memoryStream.ToArray()).Dump();
}
private void ImageSharpImpl(int width, int height)
{
using var image = new Image<Rgba32>(64, 64);
var brush = SixLabors.ImageSharp.Drawing.Processing.Brushes.Solid(SixLabors.ImageSharp.Color.Green);
var pen = SixLabors.ImageSharp.Drawing.Processing.Pens.Solid(SixLabors.ImageSharp.Color.Green, 0.1f);
var ellipse = new EllipsePolygon(32, 32, width, height);
image.Mutate(ctx => ctx.Draw(pen, ellipse));
var memoryStream = new MemoryStream();
image.Save(memoryStream, new JpegEncoder());
Util.Image(memoryStream.ToArray()).Dump();
}
System.Drawing 的输出为:
来自 ImageSharp 的 output/exception 是:
ImageProcessingException: An error occurred when processing the image
using FillRegionProcessor`1. See the inner exception for more detail.
ArgumentOutOfRangeException: Specified argument was out of the range
of valid values. (Parameter 'edgeIdx')
我想知道是否有办法获得类似的输出。有没有办法让我仍然能够绘制可能的椭圆部分?
我试图通过一个简单的 where:
删除“无效”的点
var points = ellipse.Points.ToArray();
var validPoints = points.Where(x => (x.X <= image.Width && x.X >= 0) && (x.Y <= image.Height && x.Y >= 0)).ToArray();
image.Mutate(ctx => ctx.DrawPolygon(pen, validPoints));
然而,这仍然会尝试创建一个完全连接的路径,这不是预期的效果:
任何关于我如何实现这一目标的建议都将不胜感激
经过大量挖掘,我设法找到了一些答案。
我决定下载最新版本的 ImageSharp.Drawing
并执行以下我知道会引发异常的简单代码:
using var image = new Image<Rgba32>(64, 64);
var ellipse = new EllipsePolygon(32, 32, 70, 70);
image.Mutate(x => x.Draw(Color.Green, 2f, ellipse));
当我拉取存储库时,这段代码工作得很好!此代码是发布此答案时存储库的最新代码,我恢复到之前的提交,该提交大约在 ImageSharp.Drawing
的 NuGet 包发布时,10 月 8 日左右,版本 1.0 .0-beta13。这段代码现在抛出了我之前遇到的异常。
调试这段代码,我找到了抛出它的文件,并找到了它从哪里执行的,它是PolygonScanner.cs
。文件历史记录显示今年有一个更改引用了一个问题:
这个问题解决了这个区域出现的问题,似乎解决了我的问题。
因此问题已解决...在最新版本的代码中。这个包与最新的测试版有点过时了,但是在更新这个包并发布 RC 之前,我似乎可以使用一个 alpha,听起来很快就会发布!
我想是使用测试版的诅咒!
我目前正在将一个使用 System.Drawing.Bitmap
的项目迁移到使用 ImageSharp。作为此迁移的一部分,我正在迁移使用 Graphics.FromImage
函数在位图上绘制圆圈的逻辑。
我面临的问题是,如果圆圈之前超出了位图的边界,这在以前是没问题的,它会绘制圆圈的部分,只需剪裁绘制的圆圈即可。使用 ImageSharp,可以理解,这会抛出越界异常。
简化的实现:
void Main()
{
var width = 70;
var height = 70;
SystemDrawingImpl(width, height);
ImageSharpImpl(width, height);
}
private void SystemDrawingImpl(int width, int height)
{
using var bitmap = new Bitmap(64, 64);
using var graphics = Graphics.FromImage(bitmap);
var xLocation = ((bitmap.Width / 2) - (width / 2)) - 1;
var yLocation = ((bitmap.Height / 2) - (height / 2)) - 1;
graphics.DrawEllipse(new System.Drawing.Pen(System.Drawing.Color.Green, 1.1f), xLocation, yLocation, width, height);
var memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Jpeg);
Util.Image(memoryStream.ToArray()).Dump();
}
private void ImageSharpImpl(int width, int height)
{
using var image = new Image<Rgba32>(64, 64);
var brush = SixLabors.ImageSharp.Drawing.Processing.Brushes.Solid(SixLabors.ImageSharp.Color.Green);
var pen = SixLabors.ImageSharp.Drawing.Processing.Pens.Solid(SixLabors.ImageSharp.Color.Green, 0.1f);
var ellipse = new EllipsePolygon(32, 32, width, height);
image.Mutate(ctx => ctx.Draw(pen, ellipse));
var memoryStream = new MemoryStream();
image.Save(memoryStream, new JpegEncoder());
Util.Image(memoryStream.ToArray()).Dump();
}
System.Drawing 的输出为:
来自 ImageSharp 的 output/exception 是:
ImageProcessingException: An error occurred when processing the image using FillRegionProcessor`1. See the inner exception for more detail.
ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'edgeIdx')
我想知道是否有办法获得类似的输出。有没有办法让我仍然能够绘制可能的椭圆部分?
我试图通过一个简单的 where:
删除“无效”的点var points = ellipse.Points.ToArray();
var validPoints = points.Where(x => (x.X <= image.Width && x.X >= 0) && (x.Y <= image.Height && x.Y >= 0)).ToArray();
image.Mutate(ctx => ctx.DrawPolygon(pen, validPoints));
然而,这仍然会尝试创建一个完全连接的路径,这不是预期的效果:
任何关于我如何实现这一目标的建议都将不胜感激
经过大量挖掘,我设法找到了一些答案。
我决定下载最新版本的 ImageSharp.Drawing
并执行以下我知道会引发异常的简单代码:
using var image = new Image<Rgba32>(64, 64);
var ellipse = new EllipsePolygon(32, 32, 70, 70);
image.Mutate(x => x.Draw(Color.Green, 2f, ellipse));
当我拉取存储库时,这段代码工作得很好!此代码是发布此答案时存储库的最新代码,我恢复到之前的提交,该提交大约在 ImageSharp.Drawing
的 NuGet 包发布时,10 月 8 日左右,版本 1.0 .0-beta13。这段代码现在抛出了我之前遇到的异常。
调试这段代码,我找到了抛出它的文件,并找到了它从哪里执行的,它是PolygonScanner.cs
。文件历史记录显示今年有一个更改引用了一个问题:
这个问题解决了这个区域出现的问题,似乎解决了我的问题。
因此问题已解决...在最新版本的代码中。这个包与最新的测试版有点过时了,但是在更新这个包并发布 RC 之前,我似乎可以使用一个 alpha,听起来很快就会发布!
我想是使用测试版的诅咒!