如何在.NET Core中裁剪图像?

5

我需要在.NET Core中裁剪图像。我使用了ImageSharp、CoreCompat和Microsoft.Windows.Compatibility,并扫描了能找到的所有方法。然而,我仍然无法找到一个裁剪图像的方法。虽然有调整大小的方法,但没有裁剪的方法。

如何根据左上角像素位置、宽度和高度在.NET Core中裁剪图像?


这可能对ImageSharp有所帮助。 - Kirk Larkin
微软记录了您可以尝试的所有方法,https://blogs.msdn.microsoft.com/dotnet/2017/01/19/net-core-image-processing/ ,甚至可能还有更多。 - Lex Li
@LexLi,在那个页面上提到了裁剪吗?我不是指缩放或创建缩略图。我是指例如从汽车中的苹果中获取苹果图像。 - mohammad rostami siahgeli
5个回答

2
我建议使用 ImageSharpCoreCompat.System.Drawing。 如果您使用的是 ImageSharp,我认为这是裁剪图片的正确方式;通过 Mutate() 方法使用 ImageProcessors:
int width = 0;
int height = 0;
image.Mutate(ctx => ctx.Crop(width, height));

您需要以下命名空间才能访问此内容:
using SixLabors.ImageSharp.Processing;

1
如果您打算使用CoreCompat.System.Drawing,请改用System.Drawing.Common。它作为.NET Core的一部分提供相同的功能,但维护得更好。 - Frederik Carlier
using SixLabors.ImageSharp.Advanced;No you don't. You need SixLabors.ImageSharp.Processing - James South

1
你可以使用 ImageSharp库。它有一种基于左上角裁剪图像的方法。请看下面的示例:
private async static Task CropImage()
{
    using (var httpClient = new HttpClient())
    {
        var response = await httpClient.GetAsync("https://assets-cdn.github.com/images/modules/logos_page/GitHub-Mark.png")
            .ConfigureAwait(false);

        using (var inputStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
        {
            using (var image = Image.Load(inputStream))
            {
                var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "foo.png");

                image.Clone(
                    ctx => ctx.Crop(560, 300)).Save(path);
            }
        }
    }
}

1
Crop 还有一个重载,接受一个矩形参数。 - James South

1
只需安装以下软件包:

System.Drawing.Common package

使用以下代码:
using SD = System.Drawing;

static byte[] Crop(string Img, int Width, int Height, int X, int Y)
{
    try
    {
        using (SD.Image OriginalImage = SD.Image.FromFile(Img))
        {
            using (SD.Bitmap bmp = new SD.Bitmap(Width, Height))
            {
                bmp.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution);

                using (SD.Graphics Graphic = SD.Graphics.FromImage(bmp))
                {
                    Graphic.SmoothingMode = SmoothingMode.AntiAlias;

                    Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;

                    Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;

                    Graphic.DrawImage(OriginalImage, new SD.Rectangle(0, 0, Width, Height), X, Y, Width, Height, SD.GraphicsUnit.Pixel);

                    MemoryStream ms = new MemoryStream();

                    bmp.Save(ms, OriginalImage.RawFormat);

                    return ms.GetBuffer();

                }
            }
        }
    }
    catch (Exception Ex)
    {
        throw (Ex);
    }
}

这个答案基于一篇很棒的文章在这里。然而,通过安装提到的包,可以修改为在 .net Core 2.x 及以上版本下运行。顺便说一句,其他著名的包也使用了相同的核心库。
正如你所看到的,与其他答案中提到的著名库相比,你在裁剪方面拥有更多的灵活性。

更灵活?不要散布恐惧。同时不要使用 ms.GetBuffer(),因为它可能是一个比写入的像素数据更大的字节数组。 - James South
关于三年后的FUD:https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only - Marc Wittke

0

您可以使用Bitmap.Clone(Rectangle rect, PixelFormat format)方法,例如,作为Bitmap的扩展:

using System.Drawing;

static public class BitmapExtensions
{
    static public Bitmap Crop(this Bitmap bitmap, Rectangle rect)
    {
        return bitmap.Clone(rect, bitmap.PixelFormat);
    }
}

0

首先安装“System.Drawing.Common”包。

using System.Drawing;
using System.Drawing.Imaging;

...

public byte[] Crop(string path, int width, int height)
{
    Image img = Image.FromFile(path);
    Bitmap bmp = new Bitmap(width, height);
    bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution);
    Graphics g = Graphics.FromImage(bmp);
    g.DrawImage(img, 0, 0);
    using (MemoryStream ms = new MemoryStream())
    {
        bmp.Save(ms, ImageFormat.Jpeg);
        return ms.ToArray();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接