Při vytváření a manipulaci s digitálním obsahem je odstranění pozadí z obrázků běžným a zásadním úkolem. Ať už pracujete na grafickém designu, e-commerce nebo jakémkoli jiném vizuálním projektu, schopnost izolovat objekty od jejich pozadí rozšiřuje vaši kreativitu. V tomto příspěvku na blogu prozkoumáme, jak odstranit pozadí z obrázků programově v C#.
- Knihovna C# pro odstranění pozadí z obrázků
- Odstranění pozadí obrázku pomocí automatického maskování
- Odstranění pozadí pomocí ručního maskování
Knihovna C# pro odstranění pozadí z obrázků
K odstranění pozadí z obrázků použijeme Aspose.Imaging for .NET – výkonnou knihovnu, která poskytuje širokou škálu funkcí pro zpracování obrázků pro aplikace .NET. Podporuje různé formáty obrázků a umožňuje vývojářům snadno provádět operace, jako je změna velikosti, oříznutí, otočení a samozřejmě odstranění pozadí.
API si můžete buď stáhnout, nebo jej nainstalovat z NuGet.
PM> Install-Package Aspose.Imaging
Odstranění pozadí obrázku pomocí automatického maskování v C#
Chcete-li získat lepší výsledky odstraňování pozadí, upřednostňuje se metoda automatického maskování. Cílem je vytvořit masku, která přesně identifikuje pixely patřící do popředí a pixely patřící do pozadí. Aspose.Imaging poskytuje tři techniky automatického maskování pro odstranění pozadí z obrázku, jak je popsáno v následujících částech.
Automatické maskování grafu s prolnutím
V této technice rozhraní API provádí maskování obrazu s prolnutím na základě velikosti obrazu a používá automaticky vypočítané výchozí tahy. Následující fragment kódu ukazuje, jak používat automatické maskování řezu grafu s prolnutím. Vlastnost Args AutoMaskingGraphCutOptions lze vynechat, protože tam jsou nakonec umístěny výchozí tahy.
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"))
{
// Chcete-li použít Graph Cut s automaticky vypočítanými tahy, použije se AutoMaskingGraphCutOptions.
AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
{
// Indikuje, že během rozkladu obrazu by měl být proveden nový výpočet výchozích tahů.
CalculateDefaultStrokes = true,
// Nastavení poloměru prolnutí po zpracování na základě velikosti obrázku.
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");
Následující snímek obrazovky ukazuje vstupní a výstupní obrázky.
Opětovné použití výchozích tahů v opakovaném automatickém maskování
V této technice se maskování obrazu provádí pomocí automaticky vypočítaných výchozích tahů, avšak API znovu používá možnosti maskování pro novou iteraci maskování. V následujícím fragmentu kódu si můžete všimnout, že data dvou předpokládaných objektů jsou také specifikována ve vlastnosti AssumedObjects AutoMaskingGraphCutOptions. Po počátečních výsledcích maskování se provedou úpravy aplikovaných tahů pozadí/popředí a provede se následná iterace masková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;
// Pro zlepšení výsledků maskování by mohla být poskytnuta data konkrétních objektů, které by měly být zahrnuty do výsledku maskování popředí.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// Měl by být specifikován typ objektu a oblast obsahující tento objekt.
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"))
{
// Chcete-li použít Graph Cut s automaticky vypočítanými tahy, použije se AutoMaskingGraphCutOptions.
options = new AutoMaskingGraphCutOptions
{
AssumedObjects = assumedObjects,
// Indikuje, že během rozkladu obrazu by měl být proveden nový výpočet výchozích tahů.
CalculateDefaultStrokes = true,
// Nastavení poloměru prolnutí po zpracování na základě velikosti obrázku.
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();
// Ukládání mezivýsledku maskování.
using (RasterImage resultImage = results[1].GetImage())
{
resultImage.Save(dataDir + "result2.png",
new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
}
// V tomto bodě mohou být aplikované tahy popředí/pozadí analyzovány a na jejich základě další
// tahy popředí/pozadí lze zadat ručně.
appliedBackgroundStrokes = options.DefaultBackgroundStrokes;
appliedForegroundStrokes = options.DefaultForegroundStrokes;
appliedObjectRectangles = options.DefaultObjectsRectangles;
// Při opětovném použití AutoMaskingGraphCutOptions není nutné provádět výchozí výpočty zdvihu podruhé.
// Když jsou k dispozici výchozí tahy i ObjectsPoints ve vlastnosti Args AutoMaskingArgs, pole Point se nakonec zkombinují.
// První pole ObjectsPoints je považováno za pole bodů pozadí a
// druhé pole ObjectsPoints je považováno za pole bodů v popředí.
// Když jsou ve vlastnosti Args AutoMaskingArgs k dispozici jak DefaultObjectsRectangles, tak ObjectsRectangles,
// používá se pouze pole z Args.
AutoMaskingArgs newAutoMaskingArgs = new AutoMaskingArgs()
{
ObjectsPoints = new Point[][]
{
// Dodatečně specifikující oblasti, které chceme odstranit.
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 });
}
}
}
//Příklady - graf - řez - opakování - maskování - s - nové- body.cs
// Pro zlepšení výsledků maskování by mohla být poskytnuta data konkrétních objektů, které by měly být zahrnuty do výsledku maskování popředí.
assumedObjects = new List<AssumedObjectData>();
// Měl by být specifikován typ objektu a oblast obsahující tento objekt.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(100, 100, 150, 300)));
// Provede se první iterace maskování, aby se získaly automaticky vypočítané tahy štětcem popředí/pozadí.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
// Chcete-li použít Graph Cut s automaticky vypočítanými tahy, použije se AutoMaskingGraphCutOptions.
options = new AutoMaskingGraphCutOptions
{
AssumedObjects = assumedObjects,
// Indikuje, že během rozkladu obrazu by měl být proveden nový výpočet výchozích tahů.
CalculateDefaultStrokes = true,
// Nastavení poloměru prolnutí po zpracování.
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);
// V tomto bodě mohou být aplikované tahy popředí/pozadí analyzovány a na jejich základě další
// tahy popředí/pozadí lze zadat ručně.
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 });
}
}
// Druhá iterace maskování se provádí za účelem dalšího zlepšení kvality maskování přidáním nových ručně vybraných bodů popředí/pozadí.
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
// Při opětovném použití AutoMaskingGraphCutOptions není nutné provádět výchozí výpočty zdvihu podruhé.
options.CalculateDefaultStrokes = false;
// Když jsou k dispozici výchozí tahy i ObjectsPoints ve vlastnosti Args AutoMaskingArgs, pole Point se nakonec zkombinují.
// První pole ObjectsPoints je považováno za pole bodů pozadí a
// druhé pole ObjectsPoints je považováno za pole bodů v popředí.
// Když jsou ve vlastnosti Args AutoMaskingArgs k dispozici jak DefaultObjectsRectangles, tak ObjectsRectangles,
// používá se pouze pole z 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);
// Uložení konečného výsledku maskování.
using (RasterImage resultImage = (RasterImage)results[1].GetImage())
{
resultImage.Save(dataDir + "result6.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
}
}
///<summary>
/// Vrátit všechny body, které patří do zadaných obdélníků.
///</summary>
///<param name="rectangles"> Pole obdélníků.</param>
///<returns> Všechny body obdélníku.</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");
Následující snímek obrazovky ukazuje vstupní a výstupní obrázky.
Automatické maskování řezu grafu se zadanými údaji o předpokládaném objektu
V této technice jsou data konkrétního předpokládaného objektu použita ve vlastnosti AssumedObjects AutoMaskingGraphCutOptions, která se používá v následných iteracích maskování. Následující fragment kódu ukazuje, jak použít automatické maskování řezu grafu s jedním předpokládaným objektem k odstranění pozadí obrázku.
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;
// Pro zlepšení výsledků maskování by mohla být poskytnuta data konkrétních objektů, které by měly být zahrnuty do výsledku maskování popředí.
List<AssumedObjectData> assumedObjects = new List<AssumedObjectData>();
// Měl by být specifikován typ objektu a oblast obsahující tento objekt.
assumedObjects.Add(new AssumedObjectData(DetectedObjectType.Human, new Rectangle(0, 0, 256, 365)));
MaskingResult results;
using (RasterImage image = (RasterImage)Image.Load(dataDir + "couple.jpg"))
{
// Chcete-li použít Graph Cut s automaticky vypočítanými tahy, použije se AutoMaskingGraphCutOptions.
AutoMaskingGraphCutOptions options = new AutoMaskingGraphCutOptions
{
AssumedObjects = assumedObjects,
// Indikuje, že během rozkladu obrazu by měl být proveden nový výpočet výchozích tahů.
CalculateDefaultStrokes = true,
// Nastavení poloměru prolnutí po zpracování na základě velikosti obrázku.
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);
// Uložení konečného výsledku maskování.
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");
Následující snímek obrazovky ukazuje vstupní a výstupní obrázky.
Odstranění pozadí obrázku pomocí ručního maskování
Pokud nemáte zájem o automatické maskování, můžete použít ruční metodu maskování k odstranění pozadí z obrázků. Následující úryvek kódu ukazuje, jak použít ruční maskování na rastrový obrázek a odstranit jeho pozadí.
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);
// Uložení konečného výsledku maskování.
using (RasterImage resultImage = (RasterImage)results[1].GetImage())
{
resultImage.Save(dataDir + "result.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
}
}
File.Delete(dataDir + "result.png");
Následující snímek obrazovky ukazuje vstupní a výstupní obrázky.
Získejte C# Image Background Remover API
Můžete získat bezplatnou dočasnou licenci a používat naši knihovnu pro úpravy obrázků a odstraňování pozadí bez jakýchkoli omezení.
Závěr
Odstranění pozadí z obrázků je zásadní dovedností při úpravách a designu obrázků. Aspose.Imaging for .NET umožňuje vývojářům přesně odstranit pozadí z obrázků v aplikacích C#. Tento blogový příspěvek pokryl základy načítání obrázků, implementaci odstranění pozadí pomocí různých metod automatického a ručního maskování a uložení výstupního obrázku.
Integrací Aspose.Imaging do vašich projektů C# můžete zefektivnit pracovní postup zpracování obrazu a odemknout novou úroveň kreativity ve vašich aplikacích. Experimentujte s různými funkcemi a technikami a objevte plný potenciál Aspose.Imaging for .NET. Také se s námi podělte o své dotazy prostřednictvím našeho fóra.