简体   繁体   English

ImageSharp:绘制一个剪裁的多边形越界

[英]ImageSharp: Drawing a clipped Polygon out of bounds

I'm currently in the process of migrating a project that uses System.Drawing.Bitmap over to use ImageSharp.我目前正在迁移一个使用System.Drawing.Bitmap的项目以使用 ImageSharp。 As part of this migration, I am migrating logic that would draw circles onto the bitmap using the Graphics.FromImage function.作为此迁移的一部分,我正在迁移使用Graphics.FromImage function 将圆圈绘制到 bitmap 的逻辑。

The problem I am faced with is, if the circle previously went outside the bounds of the Bitmap, this was previously fine and it would draw the parts of the circle it could, simply clipping the drawn circle.我面临的问题是,如果圆圈之前超出了 Bitmap 的范围,这在以前很好,它会绘制它可以绘制的圆圈部分,只需剪裁绘制的圆圈。 With ImageSharp, this would, understandably throw an out of bounds exception.使用 ImageSharp,这会抛出一个越界异常,这是可以理解的。

A simplified implementation:一个简化的实现:

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();
}

For which the output for System.Drawing would be: System.Drawing 的 output 将是:

在此处输入图像描述

The output/exception from ImageSharp is: ImageSharp 的输出/异常是:

ImageProcessingException: An error occurred when processing the image using FillRegionProcessor`1. ImageProcessingException:使用 FillRegionProcessor`1 处理图像时出错。 See the inner exception for more detail.有关更多详细信息,请参阅内部异常。

ArgumentOutOfRangeException: Specified argument was out of the range of valid values. ArgumentOutOfRangeException:指定的参数超出了有效值的范围。 (Parameter 'edgeIdx') (参数“edgeIdx”)

I was wondering if there was a way to get a similar output.我想知道是否有办法获得类似的 output。 Is there a way in which I'd be able to still draw the parts of the ellipse that is possible?有没有办法让我仍然可以画出可能的椭圆部分?

I have attempted to remove the points that are "invalid" via a simple where:我试图通过一个简单的 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));

However this will still try to create a fully joined path which is not the desired effect:然而,这仍然会尝试创建一个完全连接的路径,这不是预期的效果:

在此处输入图像描述

Any advice on how I might achieve this would be appreciated任何关于我如何实现这一目标的建议将不胜感激

After a lot of digging I managed to find somewhat of an answer.经过大量挖掘,我设法找到了一些答案。

I decided to pull down the latest version of ImageSharp.Drawing and executed the following simple piece of code which I knew threw an exception:我决定下载最新版本的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));

This code which when I pulled the repository, works just fine, This code being the most up to date code for the repository as of this answer being posted, I reverted back to a previous commit which was around the time of the NuGet package for ImageSharp.Drawing was published, ~8th October, version 1.0.0-beta13.当我拉出存储库时,此代码工作正常,此代码是发布此答案时存储库的最新代码,我恢复到以前的提交,该提交大约是ImageSharp.Drawing的 NuGet package 时间ImageSharp.Drawing于 10 月 8 日左右发布,版本 1.0.0-beta13。 This code now threw the exception I had before.这段代码现在抛出了我之前遇到的异常。

Debugging this code, I found the file where this was thrown and found where it was executed from, it was PolygonScanner.cs .调试这段代码,我找到了抛出它的文件,并找到了它的执行位置,它是PolygonScanner.cs The file history showed this had one change this year which referenced an issue:文件历史显示,今年有一个变化,它引用了一个问题:

Issue 108 第 108 期

This issue fixed a problem which arose around this area which seemed to fix my issue.这个问题解决了这个区域出现的一个问题,这似乎解决了我的问题。

Therefore the issue is fixed... In the latest version of the code.因此问题已解决...在最新版本的代码中。 This package is somewhat out of date with the latest beta however there looks to be an alpha I can use until this package is updated and a RC is released, which sounds like it will be soon!这个 package 与最新的 beta 版本有点过时了,但是在这个 package 更新并发布 RC 之前,我似乎可以使用一个 alpha 版本,听起来很快就会!

Release Candidate Discussion 发布候选讨论

Curse of using a beta I suppose!我想使用测试版的诅咒!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM