При создании и манипулировании цифровым контентом удаление фона из изображений является распространенной и важной задачей. Независимо от того, работаете ли вы над графическим дизайном, электронной коммерцией или любым другим визуальным проектом, возможность изолировать объекты от их фона расширяет ваши творческие способности. В этой записи блога мы рассмотрим, как программно удалить фон из изображений на C#.
- Библиотека C# для удаления фона из изображений
- Удаление фона изображения с помощью автоматической маскировки
- Удаление фона с помощью ручной маскировки
Библиотека C# для удаления фона из изображений
Для удаления фона с изображений мы будем использовать Aspose.Imaging for .NET — мощную библиотеку, предоставляющую широкий набор функций обработки изображений для .NET-приложений. Он поддерживает различные форматы изображений и позволяет разработчикам с легкостью выполнять такие операции, как изменение размера, обрезка, поворот и, конечно же, удаление фона.
Вы можете либо скачать API, либо установить его из NuGet.
PM> Install-Package Aspose.Imaging
Удаление фона изображения с помощью автоматической маскировки в C#
Чтобы получить лучшие результаты удаления фона, предпочтительным является метод автоматической маскировки. Цель состоит в том, чтобы создать маску, которая точно идентифицирует пиксели, принадлежащие переднему плану, и пиксели, принадлежащие фоновому. Aspose.Imaging предоставляет три метода автоматической маскировки для удаления фона из изображения, как описано в следующих разделах.
Автоматическое маскирование Graph Cut с растушевкой
В этом методе 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");
На следующем снимке экрана показаны входные и выходные изображения.
Повторное использование обводок по умолчанию при повторяющейся автоматической маскировке
В этом методе маскирование изображения выполняется с использованием автоматически рассчитанных штрихов по умолчанию, однако 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 нет необходимости повторно выполнять вычисления обводки по умолчанию.
// Если в свойстве Args AutoMaskingArgs указаны как штрихи по умолчанию, так и ObjectsPoints, массивы Point в конечном итоге объединяются.
// Первый массив ObjectsPoints считается массивом фоновых точек и
// второй массив ObjectsPoints считается массивом точек переднего плана.
// Если в свойстве Args AutoMaskingArgs указаны как DefaultObjectsRectangles, так и ObjectsRectangles,
// используется только массив из 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;
// Если в свойстве Args AutoMaskingArgs указаны как штрихи по умолчанию, так и ObjectsPoints, массивы Point в конечном итоге объединяются.
// Первый массив ObjectsPoints считается массивом фоновых точек и
// второй массив ObjectsPoints считается массивом точек переднего плана.
// Если в свойстве Args AutoMaskingArgs указаны как DefaultObjectsRectangles, так и ObjectsRectangles,
// используется только массив из 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");
На следующем снимке экрана показаны входные и выходные изображения.
Получите API для удаления фона изображения C#
Вы можете получить бесплатную временную лицензию и использовать нашу библиотеку редактирования изображений и удаления фона без каких-либо ограничений.
Заключение
Удаление фона из изображений — важнейший навык в редактировании и дизайне изображений. Aspose.Imaging for .NET позволяет разработчикам точно удалять фон из изображений в приложениях C#. В этом сообщении блога были рассмотрены основы загрузки изображений, реализация удаления фона с использованием различных методов автоматического и ручного маскирования, а также сохранение выходного изображения.
Интегрировав Aspose.Imaging в свои проекты C#, вы сможете оптимизировать рабочий процесс обработки изображений и открыть новый уровень творчества в своих приложениях. Поэкспериментируйте с различными функциями и методами, чтобы раскрыть весь потенциал Aspose.Imaging for .NET. Также поделитесь с нами своими вопросами через наш форум.