Bildhintergrund entfernen C#

Bei der Erstellung und Bearbeitung digitaler Inhalte ist das Entfernen des Hintergrunds aus Bildern eine häufige und wesentliche Aufgabe. Unabhängig davon, ob Sie an Grafikdesign, E-Commerce oder einem anderen visuellen Projekt arbeiten, erweitert die Möglichkeit, Objekte von ihrem Hintergrund zu isolieren, Ihre Kreativität. In diesem Blogbeitrag erfahren Sie, wie Sie in C# programmgesteuert den Hintergrund von Bildern entfernen.

C#-Bibliothek zum Entfernen des Hintergrunds aus Bildern

Um den Hintergrund von Bildern zu entfernen, verwenden wir Aspose.Imaging for .NET – eine leistungsstarke Bibliothek, die eine breite Palette von Bildverarbeitungsfunktionen für .NET-Anwendungen bereitstellt. Es unterstützt verschiedene Bildformate und ermöglicht Entwicklern die einfache Durchführung von Vorgängen wie Größenänderung, Zuschneiden, Drehen und natürlich Entfernen von Hintergründen.

Sie können die API entweder herunterladen oder über NuGet installieren.

PM> Install-Package Aspose.Imaging

Bildhintergrund mit automatischer Maskierung in C# entfernen

Um bessere Ergebnisse beim Entfernen des Hintergrunds zu erzielen, wird die automatische Maskierungsmethode bevorzugt. Ziel ist es, eine Maske zu erstellen, die die zum Vordergrund und zum Hintergrund gehörenden Pixel genau identifiziert. Aspose.Imaging bietet drei automatische Maskierungstechniken zum Entfernen des Hintergrunds aus dem Bild, wie in den folgenden Abschnitten beschrieben.

Automatische Maskierung von Graph Cut mit Feathering

Bei dieser Technik führt die API eine Bildmaskierung mit Auslaufen basierend auf der Bildgröße durch und verwendet automatisch berechnete Standardstriche. Der folgende Codeausschnitt zeigt, wie die automatische Maskierung von Diagrammschnitten mit Auslaufen verwendet wird. Die Args-Eigenschaft von AutoMaskingGraphCutOptions kann weggelassen werden, da dort am Ende Standardstriche platziert werden.

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"))
{
    // Um Graph Cut mit automatisch berechneten Strichen zu verwenden, wird AutoMaskingGraphCutOptions verwendet.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        // Gibt an, dass während der Bildzerlegung eine neue Berechnung der Standardstriche durchgeführt werden soll.
        CalculateDefaultStrokes = true,
        // Festlegen des Nachbearbeitungsradius für die Ausfransung basierend auf der Bildgröße.
        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");

Der folgende Screenshot zeigt die Eingabe und Ausgabebilder.

Bildhintergrund in C# entfernen

Wiederverwendung von Standardstrichen bei der wiederholten automatischen Maskierung

Bei dieser Technik erfolgt die Bildmaskierung mithilfe automatisch berechneter Standardstriche. Die API verwendet die Maskierungsoptionen jedoch für die neue Maskierungsiteration wieder. Im folgenden Codeausschnitt können Sie erkennen, dass die Daten der beiden angenommenen Objekte auch in der Eigenschaft AssumedObjects von AutoMaskingGraphCutOptions angegeben sind. Nach den ersten Maskierungsergebnissen werden Anpassungen an den angewendeten Hintergrund-/Vordergrundstrichen vorgenommen und eine anschließende Maskierungsiteration durchgeführt.

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;

// Um die Maskierungsergebnisse zu verbessern, könnten Daten zu den spezifischen Objekten bereitgestellt werden, die in das Vordergrundmaskierungsergebnis einbezogen werden sollten.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// Der Objekttyp und der Bereich, der dieses Objekt enthält, sollten angegeben werden.
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"))
{
    // Um Graph Cut mit automatisch berechneten Strichen zu verwenden, wird AutoMaskingGraphCutOptions verwendet.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // Gibt an, dass während der Bildzerlegung eine neue Berechnung der Standardstriche durchgeführt werden soll.
        CalculateDefaultStrokes = true,
        // Festlegen des Nachbearbeitungsradius für die Ausfransung basierend auf der Bildgröße.
        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();

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

        // An dieser Stelle können aufgetragene Vordergrund-/Hintergrundstriche analysiert und darauf aufbauend weiterverarbeitet werden 
        // Vordergrund-/Hintergrundstriche können manuell bereitgestellt werden.
        appliedBackgroundStrokes = options.DefaultBackgroundStrokes;
        appliedForegroundStrokes = options.DefaultForegroundStrokes;
        appliedObjectRectangles = options.DefaultObjectsRectangles;

        // Durch die Wiederverwendung von AutoMaskingGraphCutOptions ist es nicht erforderlich, die Standardstrichberechnungen ein zweites Mal durchzuführen.
        // Wenn sowohl Standardstriche als auch ObjectsPoints in der Args-Eigenschaft von AutoMaskingArgs bereitgestellt werden, werden Point-Arrays am Ende kombiniert.
        // Das erste ObjectsPoints-Array wird als Hintergrundpunktarray betrachtet und 
        // Das zweite ObjectsPoints-Array wird als Vordergrundpunkt-Array betrachtet.
        // Wenn sowohl DefaultObjectsRectangles als auch ObjectsRectangles in der Args-Eigenschaft von AutoMaskingArgs bereitgestellt werden, 
        // Es wird nur das Array aus den Args verwendet.
        AutoMaskingArgs newAutoMaskingArgs = new AutoMaskingArgs()
        {
            ObjectsPoints = new Point[][]
            {
                // Geben Sie zusätzlich Bereiche an, die entfernt werden sollen.
                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 });
        }
    }
}
//Beispiele – Diagramm – Ausschneiden – Wiederholt – Maskieren – mit – neuen Punkten.cs
// Um die Maskierungsergebnisse zu verbessern, könnten Daten zu den spezifischen Objekten bereitgestellt werden, die in das Vordergrundmaskierungsergebnis einbezogen werden sollten.
assumedObjects = new List<AssumedObjectData>();
// Der Objekttyp und der Bereich, der dieses Objekt enthält, sollten angegeben werden.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(100, 100, 150, 300)));

// Die erste Maskierungsiteration wird durchgeführt, um automatisch berechnete Vordergrund-/Hintergrundpinselstriche zu erhalten.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Um Graph Cut mit automatisch berechneten Strichen zu verwenden, wird AutoMaskingGraphCutOptions verwendet.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // Gibt an, dass während der Bildzerlegung eine neue Berechnung der Standardstriche durchgeführt werden soll.
        CalculateDefaultStrokes = true,
        // Einstellen des Auslaufradius nach der Bearbeitung.
        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);

    // An dieser Stelle können aufgetragene Vordergrund-/Hintergrundstriche analysiert und darauf aufbauend weiterverarbeitet werden 
    // Vordergrund-/Hintergrundstriche können manuell bereitgestellt werden.
    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 });
    }
}



// Die zweite Maskierungsiteration wird durchgeführt, um die Maskierungsqualität durch das Hinzufügen neuer manuell ausgewählter Vordergrund-/Hintergrundpunkte weiter zu verbessern.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Durch die Wiederverwendung von AutoMaskingGraphCutOptions ist es nicht erforderlich, die Standardstrichberechnungen ein zweites Mal durchzuführen.
    options.CalculateDefaultStrokes = false;
    // Wenn sowohl Standardstriche als auch ObjectsPoints in der Args-Eigenschaft von AutoMaskingArgs bereitgestellt werden, werden Point-Arrays am Ende kombiniert.
    // Das erste ObjectsPoints-Array wird als Hintergrundpunktarray betrachtet und 
    // Das zweite ObjectsPoints-Array wird als Vordergrundpunkt-Array betrachtet.
    // Wenn sowohl DefaultObjectsRectangles als auch ObjectsRectangles in der Args-Eigenschaft von AutoMaskingArgs bereitgestellt werden, 
    // Es wird nur das Array aus den Args verwendet.
    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);

    // Speichern des endgültigen Maskierungsergebnisses.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result6.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



///<summary>
/// Gibt alle Punkte zurück, die zu den angegebenen Rechtecken gehören.
///</summary>
///<param name="rectangles"> Das Array von Rechtecken.</param>
///<returns> Alle Rechteckpunkte.</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");

Der folgende Screenshot zeigt die Eingabe und Ausgabebilder.

Wiederholte automatische Maskierung zur Hintergrundentfernung

Automatische Maskierung des Diagrammschnitts mit angegebenen angenommenen Objektdaten

Bei dieser Technik werden die Daten eines bestimmten angenommenen Objekts in der AssumedObjects-Eigenschaft von AutoMaskingGraphCutOptions verwendet, die in nachfolgenden Maskierungsiterationen verwendet wird. Der folgende Codeausschnitt zeigt, wie die automatische Maskierung von Diagrammschnitten mit einem angenommenen Objekt verwendet wird, um den Hintergrund eines Bildes zu entfernen.

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;

// Um die Maskierungsergebnisse zu verbessern, könnten Daten der spezifischen Objekte bereitgestellt werden, die in das Vordergrundmaskierungsergebnis einbezogen werden sollten.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// Der Objekttyp und der Bereich, der dieses Objekt enthält, sollten angegeben werden.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(0, 0, 256, 365)));

MaskingResult results;
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // Um Graph Cut mit automatisch berechneten Strichen zu verwenden, wird AutoMaskingGraphCutOptions verwendet.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // Gibt an, dass während der Bildzerlegung eine neue Berechnung der Standardstriche durchgeführt werden soll.
        CalculateDefaultStrokes = true,
        // Festlegen des Nachbearbeitungsradius für die Ausfransung basierend auf der Bildgröße.
        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);

    // Speichern des endgültigen Maskierungsergebnisses.
    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");

Der folgende Screenshot zeigt die Eingabe und Ausgabebilder.

Automatische Maskierung des Diagrammschnitts mit angenommenem Objekt

Bildhintergrundentfernung mit manueller Maskierung

Wenn Sie nicht an der automatischen Maskierung interessiert sind, können Sie die manuelle Maskierungsmethode verwenden, um den Hintergrund aus Bildern zu entfernen. Der folgende Codeausschnitt zeigt, wie Sie eine manuelle Maskierung auf ein Rasterbild anwenden, um dessen Hintergrund zu entfernen.

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);
    // Speichern des endgültigen Maskierungsergebnisses.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}       

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

Der folgende Screenshot zeigt die Eingabe und Ausgabebilder.

Manuelle Maskierung zur Hintergrundentfernung

Holen Sie sich die C# API zum Entfernen von Bildhintergrund

Sie können eine kostenlose temporäre Lizenz erhalten und unsere Bildbearbeitungs und Hintergrundentfernungsbibliothek ohne Einschränkungen nutzen.

Abschluss

Das Entfernen von Hintergründen aus Bildern ist eine entscheidende Fähigkeit bei der Bildbearbeitung und -gestaltung. Mit Aspose.Imaging for .NET können Entwickler Hintergründe aus Bildern in C#-Anwendungen präzise entfernen. In diesem Blogbeitrag wurden die Grundlagen zum Laden von Bildern, zum Implementieren der Hintergrundentfernung mithilfe verschiedener Methoden der automatischen und manuellen Maskierung sowie zum Speichern des Ausgabebilds behandelt.

Durch die Integration von Aspose.Imaging in Ihre C#-Projekte können Sie den Bildverarbeitungs-Workflow optimieren und eine neue Ebene der Kreativität in Ihren Anwendungen freisetzen. Experimentieren Sie mit verschiedenen Funktionen und Techniken, um das volle Potenzial von Aspose.Imaging for .NET zu entdecken. Teilen Sie uns Ihre Fragen auch über unser Forum mit.

Siehe auch