Xóa nền hình ảnh C#

Trong việc tạo và xử lý nội dung số, việc xóa nền khỏi hình ảnh là một công việc phổ biến và cần thiết. Cho dù bạn đang làm việc về thiết kế đồ họa, thương mại điện tử hay bất kỳ dự án trực quan nào khác, khả năng tách biệt các đối tượng khỏi nền của chúng sẽ mở rộng khả năng sáng tạo của bạn. Trong bài đăng trên blog này, chúng ta sẽ khám phá cách xóa nền khỏi hình ảnh theo chương trình trong C#.

Thư viện C# để xóa nền khỏi hình ảnh

Để xóa nền khỏi hình ảnh, chúng tôi sẽ sử dụng Aspose.Imaging for .NET - một thư viện mạnh mẽ cung cấp nhiều tính năng xử lý hình ảnh cho các ứng dụng .NET. Nó hỗ trợ nhiều định dạng hình ảnh khác nhau và cho phép các nhà phát triển thực hiện các thao tác như thay đổi kích thước, cắt xén, xoay và tất nhiên là xóa nền một cách dễ dàng.

Bạn có thể tải xuống API hoặc cài đặt nó từ NuGet.

PM> Install-Package Aspose.Imaging

Xóa nền hình ảnh bằng tính năng tự động tạo mặt nạ trong C#

Để nhận được kết quả xóa nền tốt hơn, phương pháp tạo mặt nạ tự động được ưu tiên. Mục tiêu là tạo ra một mặt nạ xác định chính xác các pixel thuộc nền trước và các pixel thuộc nền. Aspose.Imaging cung cấp ba kỹ thuật tạo mặt nạ tự động để xóa nền khỏi hình ảnh, như được mô tả trong các phần sau.

Tạo mặt nạ tự động cắt đồ thị với Feathering

Trong kỹ thuật này, API thực hiện tạo mặt nạ hình ảnh bằng cách tạo lông dựa trên kích thước hình ảnh và sử dụng các nét mặc định được tính toán tự động. Đoạn mã sau đây cho thấy cách sử dụng tính năng tạo mặt nạ tự động cắt đồ thị bằng cách tạo lông vũ. Thuộc tính Args của AutoMaskingGraphCutOptions có thể được bỏ qua do các nét mặc định được đặt ở đó cuối cùng.

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.Masking;
using Aspose.Imaging.Masking.Options;
using Aspose.Imaging.Masking.Result;
using Aspose.Imaging.Sources;
using System;
using System.IO;

string templatesFolder = @"c:\Users\USER\Downloads\templates\";
string dataDir = templatesFolder;

MaskingResult results;
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Để sử dụng Cắt đồ thị với các nét được tính toán tự động, AutoMaskingGraphCutOptions sẽ được sử dụng.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        // Cho biết rằng một phép tính mới về các nét mặc định sẽ được thực hiện trong quá trình phân tách hình ảnh.
        CalculateDefaultStrokes = true,
        // Đặt bán kính lông vũ sau quá trình dựa trên kích thước hình ảnh.
        FeatheringRadius = (Math.Max(image.Width, image.Height) / 500) + 1,
        Method = SegmentationMethod.GraphCut,
        Decompose = false,
        ExportOptions =
                                                        new PngOptions()
                                                        {
                                                            ColorType = PngColorType.TruecolorWithAlpha,
                                                            Source = new FileCreateSource(dataDir + "result.png")
                                                        },
        BackgroundReplacementColor = Color.Transparent
    };

    results = new ImageMasking(image).Decompose(options);

    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result2.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



File.Delete(dataDir + "result.png");
File.Delete(dataDir + "result2.png");

Ảnh chụp màn hình sau đây hiển thị hình ảnh đầu vào và đầu ra.

xóa nền ảnh trong C#

Sử dụng lại các nét mặc định trong tạo mặt nạ tự động lặp đi lặp lại

Trong kỹ thuật này, việc tạo mặt nạ hình ảnh được thực hiện bằng cách sử dụng các nét mặc định được tính toán tự động, tuy nhiên, API sử dụng lại các tùy chọn tạo mặt nạ cho lần lặp tạo mặt nạ mới. Trong đoạn mã sau, bạn có thể nhận thấy rằng dữ liệu của hai đối tượng giả định cũng được chỉ định trong thuộc tính AssumedObjects của AutoMaskingGraphCutOptions. Sau các kết quả tạo mặt nạ ban đầu, các điều chỉnh được thực hiện đối với các nét nền/tiền cảnh được áp dụng và việc lặp lại mặt nạ tiếp theo được thực hiện.

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.Masking;
using Aspose.Imaging.Masking.Options;
using Aspose.Imaging.Masking.Result;
using Aspose.Imaging.Sources;
using System;
using System.Collections.Generic;
using System.IO;

string templatesFolder = @"c:\Users\USER\Downloads\templates\";
string dataDir = templatesFolder;

// Để cải thiện kết quả tạo mặt nạ, dữ liệu của các đối tượng cụ thể cần được đưa vào kết quả tạo mặt nạ tiền cảnh có thể được cung cấp.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// Loại đối tượng và vùng chứa đối tượng đó phải được chỉ định.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(0, 0, 300, 300)));

MaskingResult results;
AutoMaskingGraphCutOptions options;
Point[] appliedBackgroundStrokes;
Point[] appliedForegroundStrokes;
Rectangle[] appliedObjectRectangles;

using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Để sử dụng Cắt đồ thị với các nét được tính toán tự động, AutoMaskingGraphCutOptions được sử dụng.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // Cho biết rằng một phép tính mới về các nét mặc định sẽ được thực hiện trong quá trình phân tách hình ảnh.
        CalculateDefaultStrokes = true,
        // Đặt bán kính lông vũ sau quá trình dựa trên kích thước hình ảnh.
        FeatheringRadius = (Math.Max(image.Width, image.Height) / 500) + 1,
        Method = SegmentationMethod.GraphCut,
        Decompose = false,
        ExportOptions = new PngOptions()
        {
            ColorType = PngColorType.TruecolorWithAlpha,
            Source = new FileCreateSource(dataDir + "result.png")
        },
        BackgroundReplacementColor = Color.Transparent
    };

    using (IMaskingSession maskingSession = new ImageMasking(image).CreateSession(options))
    {
        results = maskingSession.Decompose();

        // Lưu kết quả che chắn trung gian.
        using (RasterImage resultImage = results[1].GetImage())
        {
            resultImage.Save(dataDir + "result2.png",
                new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
        }

        // Tại thời điểm này, các nét nền trước/nền sau được áp dụng có thể được phân tích và dựa vào đó để bổ sung thêm 
        // nét nền trước/nền sau có thể được cung cấp theo cách thủ công.
        appliedBackgroundStrokes = options.DefaultBackgroundStrokes;
        appliedForegroundStrokes = options.DefaultForegroundStrokes;
        appliedObjectRectangles = options.DefaultObjectsRectangles;

        // Khi sử dụng lại AutoMaskingGraphCutOptions, bạn không cần phải thực hiện các phép tính hành trình mặc định lần thứ hai.
        // Khi cả nét mặc định và ObjectsPoints trong thuộc tính Args của AutoMaskingArgs đều được cung cấp, các mảng Điểm sẽ được kết hợp lại.
        // Mảng ObjectsPoints đầu tiên được coi là mảng điểm nền và 
        // mảng ObjectsPoints thứ hai được coi là mảng điểm tiền cảnh.
        // Khi cả DefaultObjectsRectangles và ObjectsRectangles trong thuộc tính Args của AutoMaskingArgs đều được cung cấp, 
        // chỉ có mảng từ Args đang được sử dụng.
        AutoMaskingArgs newAutoMaskingArgs = new AutoMaskingArgs()
        {
            ObjectsPoints = new Point[][]
            {
                // Ngoài ra, chỉ định các khu vực chúng tôi muốn xóa.
                GetRectanglePoints(
                    new Rectangle(100, 100, 35, 90),
                    new Rectangle(300, 140, 95, 50)
                )
            },
        };

        results = maskingSession.ImproveDecomposition(newAutoMaskingArgs);

        using (RasterImage resultImage = results[1].GetImage())
        {
            resultImage.Save(dataDir +
                "result3.png",
                new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
        }
    }
}
//Ví dụ - biểu đồ - cắt - lặp lại - che - với - new- point.cs
// Để cải thiện kết quả tạo mặt nạ, dữ liệu của các đối tượng cụ thể cần được đưa vào kết quả tạo mặt nạ tiền cảnh có thể được cung cấp.
assumedObjects = new List<AssumedObjectData>();
// Loại đối tượng và vùng chứa đối tượng đó phải được chỉ định.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(100, 100, 150, 300)));

// Lần lặp mặt nạ đầu tiên được thực hiện để có được các nét vẽ nền trước/nền sau được tính toán tự động.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Để sử dụng Cắt đồ thị với các nét được tính toán tự động, AutoMaskingGraphCutOptions được sử dụng.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // Cho biết rằng một phép tính mới về các nét mặc định sẽ được thực hiện trong quá trình phân tách hình ảnh.
        CalculateDefaultStrokes = true,
        // Đặt bán kính lông vũ sau quá trình.
        FeatheringRadius = 3,
        Method = SegmentationMethod.GraphCut,
        Decompose = false,
        ExportOptions =
                            new PngOptions()
                            {
                                ColorType = PngColorType.TruecolorWithAlpha,
                                Source = new FileCreateSource(dataDir + "result4.png")
                            },
        BackgroundReplacementColor = Color.Transparent
    };

    results = new ImageMasking(image).Decompose(options);

    // Tại thời điểm này, các nét nền trước/nền sau được áp dụng có thể được phân tích và dựa vào đó để bổ sung thêm 
    // nét nền trước/nền sau có thể được cung cấp theo cách thủ công.
    appliedBackgroundStrokes = options.DefaultBackgroundStrokes;
    appliedForegroundStrokes = options.DefaultForegroundStrokes;
    appliedObjectRectangles = options.DefaultObjectsRectangles;
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result5.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



// Việc lặp lại mặt nạ thứ hai được thực hiện để cải thiện hơn nữa chất lượng mặt nạ bằng cách thêm các điểm nền trước/nền sau được chọn thủ công mới.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Khi sử dụng lại AutoMaskingGraphCutOptions, bạn không cần phải thực hiện các phép tính hành trình mặc định lần thứ hai.
    options.CalculateDefaultStrokes = false;
    // Khi cả nét mặc định và ObjectsPoints trong thuộc tính Args của AutoMaskingArgs đều được cung cấp, các mảng Điểm sẽ được kết hợp lại.
    // Mảng ObjectsPoints đầu tiên được coi là mảng điểm nền và 
    // mảng ObjectsPoints thứ hai được coi là mảng điểm tiền cảnh.
    // Khi cả DefaultObjectsRectangles và ObjectsRectangles trong thuộc tính Args của AutoMaskingArgs đều được cung cấp, 
    // chỉ có mảng từ Args đang được sử dụng.
    options.Args = new AutoMaskingArgs()
    {
        ObjectsPoints = new Point[][]
                                                {
                                                    new Point[] { new Point(100, 100), new Point(150, 100) },
                                                    new Point[] { new Point(300, 200) },
                                                },
        ObjectsRectangles = new Rectangle[]
                                                    {
                                                        new Rectangle(100, 100, 300, 300),
                                                    }
    };

    results = new ImageMasking(image).Decompose(options);

    // Lưu kết quả tạo mặt nạ cuối cùng.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result6.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



///<summary>
/// Trả về tất cả các điểm thuộc hình chữ nhật được chỉ định.
///</summary>
///<param name="rectangles"> Mảng hình chữ nhật.</param>
///<returns> Tất cả các điểm hình chữ nhật.</returns>
static Point[] GetRectanglePoints(params Rectangle[] rectangles)
{
    int arraySize = 0;
    foreach (Rectangle rectangle in rectangles)
    {
        arraySize += rectangle.Width * rectangle.Height;
    }

    Point[] pointArray = new Point[arraySize];
    int arrayIndex = 0;
    foreach (Rectangle rectangle in rectangles)
    {
       for (int x = rectangle.Left; x < rectangle.Right; x++)
        {
           for (int y = rectangle.Top; y < rectangle.Bottom; y++)
            {
                pointArray[arrayIndex++] = new Point(x, y);
            }
        }
    }

    return pointArray;
}


File.Delete(dataDir + "result.png");
File.Delete(dataDir + "result2.png");
File.Delete(dataDir + "result3.png");
File.Delete(dataDir + "result4.png");
File.Delete(dataDir + "result5.png");
File.Delete(dataDir + "result6.png");

Ảnh chụp màn hình sau đây hiển thị hình ảnh đầu vào và đầu ra.

Tự động tạo mặt nạ lặp đi lặp lại để xóa nền

Tạo mặt nạ tự động cắt đồ thị với dữ liệu đối tượng giả định được chỉ định

Trong kỹ thuật này, dữ liệu của một đối tượng giả định cụ thể được sử dụng trong thuộc tính AssumedObjects của AutoMaskingGraphCutOptions, được sử dụng trong các lần lặp mặt nạ tiếp theo. Đoạn mã sau đây cho biết cách sử dụng tính năng tạo mặt nạ tự động cắt biểu đồ với một đối tượng giả định để xóa nền của hình ảnh.

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.Masking;
using Aspose.Imaging.Masking.Options;
using Aspose.Imaging.Masking.Result;
using Aspose.Imaging.Sources;
using System;
using System.Collections.Generic;
using System.IO;

string templatesFolder = @"c:\Users\USER\Downloads\templates\";
string dataDir = templatesFolder;

// Để cải thiện kết quả tạo mặt nạ, dữ liệu của các đối tượng cụ thể cần được đưa vào kết quả tạo mặt nạ tiền cảnh có thể được cung cấp.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// Loại đối tượng và vùng chứa đối tượng đó phải được chỉ định.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(0, 0, 256, 365)));

MaskingResult results;
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Để sử dụng Cắt đồ thị với các nét được tính toán tự động, AutoMaskingGraphCutOptions sẽ được sử dụng.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // Cho biết rằng một phép tính mới về các nét mặc định sẽ được thực hiện trong quá trình phân tách hình ảnh.
        CalculateDefaultStrokes = true,
        // Đặt bán kính lông vũ sau quá trình dựa trên kích thước hình ảnh.
        FeatheringRadius = (Math.Max(image.Width, image.Height) / 500) + 1,
        Method = SegmentationMethod.GraphCut,
        Decompose = false,
        ExportOptions =
                                                        new PngOptions()
                                                        {
                                                            ColorType = PngColorType.TruecolorWithAlpha,
                                                            Source = new FileCreateSource(dataDir + "result.png")
                                                        },
        BackgroundReplacementColor = Color.Transparent
    };

    results = new ImageMasking(image).Decompose(options);

    // Lưu kết quả tạo mặt nạ cuối cùng.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result2.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



File.Delete(dataDir + "result.png");
File.Delete(dataDir + "result2.png");

Ảnh chụp màn hình sau đây hiển thị hình ảnh đầu vào và đầu ra.

Tạo mặt nạ tự động cắt đồ thị với đối tượng giả định

Xóa nền hình ảnh bằng cách sử dụng mặt nạ thủ công

Nếu bạn không quan tâm đến việc tạo mặt nạ tự động, bạn có thể sử dụng phương pháp tạo mặt nạ thủ công để xóa nền khỏi hình ảnh. Đoạn mã sau đây cho biết cách áp dụng mặt nạ thủ công cho hình ảnh raster để xóa nền của nó.

using Aspose.Imaging;
using Aspose.Imaging.FileFormats.Png;
using Aspose.Imaging.ImageOptions;
using Aspose.Imaging.Masking;
using Aspose.Imaging.Masking.Options;
using Aspose.Imaging.Masking.Result;
using Aspose.Imaging.Shapes;
using Aspose.Imaging.Sources;
using System.IO;

string templatesFolder = @"c:\Users\USER\Downloads\templates\";
string dataDir = templatesFolder;

string sourceFileName = dataDir + "couple.png";
GraphicsPath manualMask = new GraphicsPath();
Figure firstFigure = new Figure();
firstFigure.AddShape(new EllipseShape(new RectangleF(100, 30, 40, 40)));
firstFigure.AddShape(new RectangleShape(new RectangleF(10, 200, 50, 30)));
manualMask.AddFigure(firstFigure);
GraphicsPath subPath = new GraphicsPath();
Figure secondFigure = new Figure();
secondFigure.AddShape(
    new PolygonShape(
     new PointF[]
     {
         new PointF(310, 100), new PointF(350, 200), new PointF(250, 200)

     }, true));

secondFigure.AddShape(new PieShape(new RectangleF(10, 10, 80, 80), 30, 120));
subPath.AddFigure(secondFigure);
manualMask.AddPath(subPath);
using (RasterImage image = (RasterImage)Image.Load(sourceFileName))
{
    MaskingOptions maskingOptions = new MaskingOptions()
    {
        Method = SegmentationMethod.Manual,
        Args = new ManualMaskingArgs
        {
            Mask = manualMask
        },
        Decompose = false,
        ExportOptions =
      new PngOptions()
      {
          ColorType = PngColorType.TruecolorWithAlpha,
          Source = new StreamSource(new MemoryStream())
      },
    };
    MaskingResult results = new ImageMasking(image).Decompose(maskingOptions);
    // Lưu kết quả tạo mặt nạ cuối cùng.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}       

File.Delete(dataDir + "result.png");

Ảnh chụp màn hình sau đây hiển thị hình ảnh đầu vào và đầu ra.

Tạo mặt nạ thủ công để xóa nền

Nhận API xóa nền hình ảnh C#

Bạn có thể nhận giấy phép tạm thời miễn phí và sử dụng thư viện chỉnh sửa hình ảnh và xóa nền của chúng tôi mà không có bất kỳ giới hạn nào.

Phần kết luận

Xóa nền khỏi hình ảnh là một kỹ năng quan trọng trong chỉnh sửa và thiết kế hình ảnh. Aspose.Imaging for .NET cho phép các nhà phát triển xóa nền khỏi hình ảnh một cách chính xác trong ứng dụng C#. Bài đăng trên blog này đề cập đến những kiến thức cơ bản về tải hình ảnh, thực hiện xóa nền bằng các phương pháp tạo mặt nạ tự động và thủ công khác nhau cũng như lưu hình ảnh đầu ra.

Bằng cách tích hợp Aspose.Imaging vào các dự án C# của bạn, bạn có thể hợp lý hóa quy trình xử lý hình ảnh và mở ra cấp độ sáng tạo mới trong ứng dụng của mình. Thử nghiệm với các tính năng và kỹ thuật khác nhau để khám phá toàn bộ tiềm năng của Aspose.Imaging for .NET. Ngoài ra, hãy chia sẻ thắc mắc của bạn với chúng tôi qua diễn đàn của chúng tôi.

Xem thêm