הסרת רקע תמונה C#

ביצירת תוכן דיגיטלי ובמניפולציה, הסרת הרקע מהתמונות היא משימה נפוצה ומהותית. בין אם אתה עובד על עיצוב גרפי, מסחר אלקטרוני או כל פרויקט ויזואלי אחר, היכולת לבודד אובייקטים מהרקע שלהם מרחיבה את היצירתיות שלך. בפוסט זה בבלוג, נחקור כיצד להסיר רקע מתמונות באופן תוכנתי ב-C#.

ספריית C# להסרת רקע מתמונות

להסרת רקע מתמונות, נשתמש ב-Aspose.Imaging for .NET - ספרייה רבת עוצמה המספקת מגוון רחב של תכונות עיבוד תמונה עבור יישומי NET. הוא תומך בפורמטים שונים של תמונה ומאפשר למפתחים לבצע פעולות כמו שינוי גודל, חיתוך, סיבוב וכמובן הסרת רקעים בקלות.

אתה יכול להוריד את ה-API או להתקין אותו מ-NuGet.

PM> Install-Package Aspose.Imaging

הסרת רקע תמונה עם מיסוך אוטומטי ב-C#{#הסרת-תמונה-רקע-עם-מסיכה אוטומטית}

כדי לקבל תוצאות טובות יותר להסרת רקע, שיטת מיסוך אוטומטי מועדפת. המטרה היא ליצור מסכה המזהה במדויק את הפיקסלים השייכים לחזית ואלו השייכים לרקע. Aspose.Imaging מספקת שלוש טכניקות מיסוך אוטומטי להסרת רקע מהתמונה, כמתואר בסעיפים הבאים.

מיסוך אוטומטי בחיתוך גרף עם נוצות

בטכניקה זו, ה-API מבצע מיסוך תמונה עם נוצות בהתבסס על גודל התמונה ומשתמש בתנועות ברירת מחדל מחושבות אוטומטיות. קטע הקוד הבא מראה כיצד להשתמש במיסוך אוטומטי בחיתוך גרף עם נוצות. ניתן להשמיט את המאפיין Args של AutoMaskingGraphCutOptions מכיוון שבסוף ממוקמים שם קוי ברירת מחדל.

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"))
{
    // כדי להשתמש ב-Graph Cut עם משיכות מחושבות אוטומטיות, נעשה שימוש ב-AutoMaskingGraphCutOptions.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        // מציין כי יש לבצע חישוב חדש של משיכות ברירת המחדל במהלך פירוק התמונה.
        CalculateDefaultStrokes = true,
        // הגדרת רדיוס נוצות לאחר תהליך בהתבסס על גודל התמונה.
        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");

צילום המסך הבא מציג את תמונות הקלט והפלט.

הסרת רקע תמונה ב-C#

שימוש חוזר בתנועות ברירת מחדל במסיכה אוטומטית חוזרת

בטכניקה זו, מיסוך התמונה נעשה באמצעות משיכות ברירת מחדל מחושבות אוטומטיות, אולם ה-API משתמש מחדש באפשרויות המיסוך עבור איטרציית המיסוך החדשה. בקטע הקוד הבא, אתה יכול לשים לב שהנתונים של שני האובייקטים המשוערים מצוינים גם במאפיין AssumedObjects של AutoMaskingGraphCutOptions. בעקבות תוצאות המיסוך הראשוניים, מתבצעות התאמות לתנועות הרקע/הקדמה המיושמות, ומתבצעת איטרציה של מיסוך לאחר מכן.

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;

// כדי לשפר את תוצאות המיסוך, ניתן לספק נתונים של האובייקטים הספציפיים שיש לכלול בתוצאת מיסוך החזית.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// יש לציין את סוג האובייקט ואת האזור המכיל את האובייקט הזה.
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"))
{
    // כדי להשתמש ב-Graph Cut עם משיכות מחושבות אוטומטיות, נעשה שימוש ב-AutoMaskingGraphCutOptions.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // מציין כי יש לבצע חישוב חדש של משיכות ברירת המחדל במהלך פירוק התמונה.
        CalculateDefaultStrokes = true,
        // הגדרת רדיוס נוצה לאחר תהליך בהתבסס על גודל התמונה.
        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();

        // שמירת תוצאת מיסוך ביניים.
        using (RasterImage resultImage = results[1].GetImage())
        {
            resultImage.Save(dataDir + "result2.png",
                new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
        }

        // בשלב זה ניתן לנתח משיכות חזית/רקע מיושמות ולהתבסס עליהן נוספות 
        // ניתן לספק משיכות קדמי/רקע באופן ידני.
        appliedBackgroundStrokes = options.DefaultBackgroundStrokes;
        appliedForegroundStrokes = options.DefaultForegroundStrokes;
        appliedObjectRectangles = options.DefaultObjectsRectangles;

        // שימוש חוזר ב-AutoMaskingGraphCutOptions אין צורך לבצע חישובי קו ברירת מחדל בפעם השנייה.
        // כאשר מסופקים גם קוי ברירת מחדל וגם ObjectsPoints במאפיין Args של AutoMaskingArgs, מערכי Point משולבים בסופו של דבר.
        // מערך ObjectsPoints הראשון נחשב למערך נקודות רקע ו 
        // מערך ה-ObjectsPoints השני נחשב למערך נקודות חזית.
        // כאשר מסופקים גם DefaultObjectsRectangles וגם ObjectsRectangles במאפיין Args של AutoMaskingArgs, 
        // רק המערך מה-Args נמצא בשימוש.
        AutoMaskingArgs newAutoMaskingArgs = new AutoMaskingArgs()
        {
            ObjectsPoints = new Point[][]
            {
                // בנוסף, ציון אזורים שאנו רוצים שיוסרו.
                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 });
        }
    }
}
//דוגמאות - גרף - חתך - חוזר - מיסוך - עם - new- points.cs
// כדי לשפר את תוצאות המיסוך, ניתן לספק נתונים של האובייקטים הספציפיים שיש לכלול בתוצאת מיסוך החזית.
assumedObjects = new List<AssumedObjectData>();
// יש לציין את סוג האובייקט ואת האזור המכיל את האובייקט הזה.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(100, 100, 150, 300)));

// איטרציית מיסוך ראשונה מבוצעת כדי לקבל משיכות מכחול מחושבות אוטומטיות בחזית/רקע.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // כדי להשתמש ב-Graph Cut עם משיכות מחושבות אוטומטיות, נעשה שימוש ב-AutoMaskingGraphCutOptions.
    options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // מציין כי יש לבצע חישוב חדש של משיכות ברירת המחדל במהלך פירוק התמונה.
        CalculateDefaultStrokes = true,
        // הגדרת רדיוס נוצות לאחר תהליך.
        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);

    // בשלב זה ניתן לנתח משיכות חזית/רקע מיושמות ולהתבסס עליהן נוספות 
    // ניתן לספק משיכות קדמי/רקע באופן ידני.
    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 });
    }
}



// חזרת מיסוך שניה מתבצעת כדי לשפר עוד יותר את איכות המיסוך על ידי הוספת נקודות חדשות שנבחרו ידנית בחזית/רקע.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // שימוש חוזר ב-AutoMaskingGraphCutOptions אין צורך לבצע חישובי קו ברירת מחדל בפעם השנייה.
    options.CalculateDefaultStrokes = false;
    // כאשר מסופקים גם קוי ברירת מחדל וגם ObjectsPoints במאפיין Args של AutoMaskingArgs, מערכי Point משולבים בסופו של דבר.
    // מערך ObjectsPoints הראשון נחשב למערך נקודות רקע ו 
    // מערך ה-ObjectsPoints השני נחשב למערך נקודות חזית.
    // כאשר מסופקים גם DefaultObjectsRectangles וגם ObjectsRectangles במאפיין Args של AutoMaskingArgs, 
    // רק המערך מה-Args נמצא בשימוש.
    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);

    // שמירת תוצאת מיסוך סופית.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result6.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}



///<summary>
/// החזר את כל הנקודות ששייכות למלבנים שצוינו.
///</summary>
///<param name="rectangles"> מערך המלבנים.</param>
///<returns> כל נקודות המלבן.</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");

צילום המסך הבא מציג את תמונות הקלט והפלט.

מיסוך אוטומטי חוזר להסרת רקע

מיסוך אוטומטי של חיתוך גרף עם נתוני אובייקט משוער שצוינו

בטכניקה זו, נעשה שימוש בנתונים של אובייקט משוער ספציפי במאפיין AssumedObjects של AutoMaskingGraphCutOptions, המשמש באיטרציות מיסוך עוקבות. קטע הקוד הבא מראה כיצד להשתמש במיסוך אוטומטי בחיתוך גרף עם אובייקט אחד משוער כדי להסיר רקע של תמונה.

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;

// כדי לשפר את תוצאות המיסוך, ניתן לספק נתונים של האובייקטים הספציפיים שיש לכלול בתוצאת מיסוך החזית.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// יש לציין את סוג האובייקט ואת האזור המכיל את האובייקט הזה.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(0, 0, 256, 365)));

MaskingResult results;
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
    // כדי להשתמש ב-Graph Cut עם משיכות מחושבות אוטומטיות, נעשה שימוש ב-AutoMaskingGraphCutOptions.
    AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
    {
        AssumedObjects = assumedObjects,
        // מציין כי יש לבצע חישוב חדש של משיכות ברירת המחדל במהלך פירוק התמונה.
        CalculateDefaultStrokes = true,
        // הגדרת רדיוס נוצות לאחר תהליך בהתבסס על גודל התמונה.
        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");

צילום המסך הבא מציג את תמונות הקלט והפלט.

חיתוך גרף מיסוך אוטומטי עם אובייקט משוער

הסרת רקע תמונה באמצעות מיסוך ידני

אם אינך מעוניין במיסוך אוטומטי, אתה יכול להשתמש בשיטת מיסוך ידני כדי להסיר רקע מהתמונות. קטע הקוד הבא מראה כיצד להחיל מיסוך ידני על תמונת רסטר כדי להסיר את הרקע שלה.

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);
    // שמירת תוצאת מיסוך סופית.
    using (RasterImage resultImage = (RasterImage)results[1].GetImage())
    {
        resultImage.Save(dataDir + "result.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
    }
}       

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

צילום המסך הבא מציג את תמונות הקלט והפלט.

מיסוך ידני להסרת רקע

קבל C# Image Background Remover API

אתה יכול לקבל רישיון זמני בחינם ולהשתמש בספריית עריכת התמונות והסרת הרקע שלנו ללא כל הגבלה.

סיכום

הסרת רקעים מתמונות היא מיומנות חיונית בעריכת ועיצוב תמונות. Aspose.Imaging עבור .NET מאפשר למפתחים להסיר במדויק רקעים מתמונות ביישומי C#. פוסט זה בבלוג כיסה את היסודות של טעינת תמונות, יישום הסרת רקע באמצעות שיטות שונות של מיסוך אוטומטי וידני, ושמירת תמונת הפלט.

על ידי שילוב של Aspose.Imaging בפרויקטי C# שלך, אתה יכול לייעל את זרימת העבודה של עיבוד התמונה ולפתוח רמה חדשה של יצירתיות ביישומים שלך. נסה עם תכונות וטכניקות שונות כדי לגלות את מלוא הפוטנציאל של Aspose.Imaging עבור .NET. כמו כן, שתף אותנו בשאילתותיך דרך הפורום שלנו.

ראה גם