如何使用 Graphicsmill 中的管道删除带有 clippingPath 的图像背景?
How to remove the background of an image with an clippingPath using a pipeline in Graphicsmill?
我有一张带有剪切路径的大图像(至少 200 MB,最大 2 GB)。我想应用剪切路径来删除背景。到目前为止,我发现的唯一解决方案 (ConvertClippingPathToMask) 使用位图,它将整个图像加载到内存中并抛出 OutOfMemoryException。
/// <summary>
/// Converts clipping path to alpha channel mask
/// </summary>
private static void ConvertClippingPathToMask()
{
using (var reader = new JpegReader("../../../../_Input/Apple.jpg"))
using (var bitmap = reader.Frames[0].GetBitmap()) // I can get rid of this line by using reader instead of bitmap in the next line, but then the OOM will throw in the next line.
using (var maskBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format8bppGrayscale, new GrayscaleColor(0)))
using (var graphics = maskBitmap.GetAdvancedGraphics())
{
var graphicsPath = reader.ClippingPaths[0].CreateGraphicsPath(reader.Width, reader.Height);
graphics.FillPath(new SolidBrush(new GrayscaleColor(255)), Path.Create(graphicsPath));
bitmap.Channels.SetAlpha(maskBitmap);
bitmap.Save("../../../../_Output/ConvertClippingPathToMask.png");
}
}
通过这种方法,始终需要位图来获取图形对象,然后应用剪切路径。
实际上,我什至不需要内存中的 maskBitmap
,因为我可以为 setAlpha 使用单独的 reader,但是:如何创建没有位图的 maskBitmap 来创建图形对象来自?
正确的方法是使用管道 API:
using (var reader = new JpegReader("ImageWithPath.jpg"))
using (var gc = new GraphicsContainer(reader))
using (var ig = new ImageGenerator(gc, PixelFormat.Format8bppGrayscale, RgbColor.Black))
using (var setAlpha = new Aurigma.GraphicsMill.Transforms.SetAlpha())
{
using (var gr = gc.GetGraphics())
{
var path = reader.ClippingPaths[0].CreateGraphicsPath(reader.Width, reader.Height);
gr.FillPath(new SolidBrush(RgbColor.White), Aurigma.GraphicsMill.AdvancedDrawing.Path.Create(path));
}
setAlpha.AlphaSource = ig;
Pipeline.Run(reader + setAlpha + "output.png");
}
为了完整起见:
来自 Aurigma.Forums 的 Fedor 解决方案涵盖了一些情况,而 Eugenes 解决方案没有。
using (var reader = ImageReader.Create("../../../PathForTest.tif"))
using (var maskGen = new ImageGenerator(reader.Width, reader.Height, PixelFormat.Format8bppGrayscale, RgbColor.Black))
using (var drawer = new Drawer())
using (var bitmap = new Bitmap())
{
var graphicsPath = Aurigma.GraphicsMill.AdvancedDrawing.Path.Create(reader.ClippingPaths[0], reader.Width, reader.Height);
drawer.Draw += (sender, e) =>
{
e.Graphics.FillPath(new SolidBrush(new GrayscaleColor(255)), graphicsPath);
};
using (var setAlpha = new SetAlpha(maskGen + drawer))
{
(reader + setAlpha + bitmap).Run();
bitmap.Save("../../../result.tif");
}
}
我有一张带有剪切路径的大图像(至少 200 MB,最大 2 GB)。我想应用剪切路径来删除背景。到目前为止,我发现的唯一解决方案 (ConvertClippingPathToMask) 使用位图,它将整个图像加载到内存中并抛出 OutOfMemoryException。
/// <summary>
/// Converts clipping path to alpha channel mask
/// </summary>
private static void ConvertClippingPathToMask()
{
using (var reader = new JpegReader("../../../../_Input/Apple.jpg"))
using (var bitmap = reader.Frames[0].GetBitmap()) // I can get rid of this line by using reader instead of bitmap in the next line, but then the OOM will throw in the next line.
using (var maskBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format8bppGrayscale, new GrayscaleColor(0)))
using (var graphics = maskBitmap.GetAdvancedGraphics())
{
var graphicsPath = reader.ClippingPaths[0].CreateGraphicsPath(reader.Width, reader.Height);
graphics.FillPath(new SolidBrush(new GrayscaleColor(255)), Path.Create(graphicsPath));
bitmap.Channels.SetAlpha(maskBitmap);
bitmap.Save("../../../../_Output/ConvertClippingPathToMask.png");
}
}
通过这种方法,始终需要位图来获取图形对象,然后应用剪切路径。
实际上,我什至不需要内存中的 maskBitmap
,因为我可以为 setAlpha 使用单独的 reader,但是:如何创建没有位图的 maskBitmap 来创建图形对象来自?
正确的方法是使用管道 API:
using (var reader = new JpegReader("ImageWithPath.jpg"))
using (var gc = new GraphicsContainer(reader))
using (var ig = new ImageGenerator(gc, PixelFormat.Format8bppGrayscale, RgbColor.Black))
using (var setAlpha = new Aurigma.GraphicsMill.Transforms.SetAlpha())
{
using (var gr = gc.GetGraphics())
{
var path = reader.ClippingPaths[0].CreateGraphicsPath(reader.Width, reader.Height);
gr.FillPath(new SolidBrush(RgbColor.White), Aurigma.GraphicsMill.AdvancedDrawing.Path.Create(path));
}
setAlpha.AlphaSource = ig;
Pipeline.Run(reader + setAlpha + "output.png");
}
为了完整起见:
来自 Aurigma.Forums 的 Fedor 解决方案涵盖了一些情况,而 Eugenes 解决方案没有。
using (var reader = ImageReader.Create("../../../PathForTest.tif"))
using (var maskGen = new ImageGenerator(reader.Width, reader.Height, PixelFormat.Format8bppGrayscale, RgbColor.Black))
using (var drawer = new Drawer())
using (var bitmap = new Bitmap())
{
var graphicsPath = Aurigma.GraphicsMill.AdvancedDrawing.Path.Create(reader.ClippingPaths[0], reader.Width, reader.Height);
drawer.Draw += (sender, e) =>
{
e.Graphics.FillPath(new SolidBrush(new GrayscaleColor(255)), graphicsPath);
};
using (var setAlpha = new SetAlpha(maskGen + drawer))
{
(reader + setAlpha + bitmap).Run();
bitmap.Save("../../../result.tif");
}
}