.NET图形 - 创建一个带透明背景的椭圆

4
以下代码将在图像上绘制一个椭圆并用番茄色填充该椭圆。
string imageWithTransEllipsePathToSaveTo = "~/Images/imageTest.png";
Graphics g = Graphics.FromImage(sourceImage);

g.FillEllipse(Brushes.Tomato, 50, 50, 200, 200);

sourceImage.Save(Server.MapPath(imageWithTransEllipsePathToSaveTo), ImageFormat.Png);

如果我将画笔更改为透明,它显然不会显示,因为椭圆形将是透明的,下面的图像将显示出来。如何将椭圆形的“背景”设置为透明,以便图像包含一个透明点?编辑:对于这样的情况,我很抱歉造成了困惑...alt text

恐怕这个非常不清楚。你能添加一张图片让我们看看最终结果应该是什么吗? - egrunin
你只能访问GDI吗?还是WPF也可以考虑? - Eilistraee
你想做的是用图像填充 GraphicsPath(假设使用 GDI)。我不确定这是否可能。 - rein
@egrunin 正确的方法是在图像上绘制一个透明的点,因为页面背景可能是多种不同的颜色甚至是图像。 - rein
@egrunin - 作为一个个人项目,我试图创建一些需要从图像中剪切透明形状的拼图碎片 - 如果可能的话? - Nicholas Murray
显示剩余4条评论
3个回答

2

这是我的第二个答案,使用图像而不是颜色刷。很遗憾我不知道有没有RadialImageBrush。我已经包括了将图像保存到磁盘的代码,并包含usings以确保您导入正确的组件。虽然它使用WPF,但它应该作为库或控制台应用程序的一部分工作。

using System.Windows.Media;
using System.Windows.Media.Imaging;
using System;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Shapes;
namespace WpfApplication30
{
    class ImageEditor
    {
        public static void processImage(string loc)
        {
            ImageSource ic = new BitmapImage(new Uri(loc, UriKind.Relative));
            ImageBrush brush = new ImageBrush(ic);
            Path p = new Path();
            p.Fill = brush;
            CombinedGeometry cb = new CombinedGeometry();
            cb.GeometryCombineMode = GeometryCombineMode.Exclude;
            EllipseGeometry ellipse = new EllipseGeometry(new Point(50, 50), 5, 5);
            RectangleGeometry rect = new RectangleGeometry(new Rect(new Size(100, 100)));
            cb.Geometry1 = rect;
            cb.Geometry2 = ellipse;
            p.Data = cb;

            Canvas inkCanvas1 = new Canvas();
            inkCanvas1.Children.Add(p);
            inkCanvas1.Height = 96;
            inkCanvas1.Width = 96;

            inkCanvas1.Measure(new Size(96, 96));
            inkCanvas1.Arrange(new Rect(new Size(96, 96)));
            RenderTargetBitmap targetBitmap =
    new RenderTargetBitmap((int)inkCanvas1.ActualWidth,
                           (int)inkCanvas1.ActualHeight,
                           96d, 96d,
                           PixelFormats.Default);
            targetBitmap.Render(inkCanvas1);

            using (System.IO.FileStream outStream = new System.IO.FileStream( loc.Replace(".png","Copy.png"), System.IO.FileMode.Create))
            {
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(targetBitmap));
                encoder.Save(outStream);
            }
        }
    }
}

这是结果: alt text

1

您需要使用半透明颜色创建画笔。

您可以使用Color.FromArgb(alpha, r, g, b)来实现,其中alpha设置不透明度。

从MSDN复制的示例

public void FromArgb1(PaintEventArgs e)
{
    Graphics     g = e.Graphics;

    // Transparent red, green, and blue brushes.
    SolidBrush trnsRedBrush = new SolidBrush(Color.FromArgb(120, 255, 0, 0));
    SolidBrush trnsGreenBrush = new SolidBrush(Color.FromArgb(120, 0, 255, 0));
    SolidBrush trnsBlueBrush = new SolidBrush(Color.FromArgb(120, 0, 0, 255));

    // Base and height of the triangle that is used to position the
    // circles. Each vertex of the triangle is at the center of one of the
    // 3 circles. The base is equal to the diameter of the circles.
    float   triBase = 100;
    float   triHeight = (float)Math.Sqrt(3*(triBase*triBase)/4);

    // Coordinates of first circle's bounding rectangle.
    float   x1 = 40;
    float   y1 = 40;

    // Fill 3 over-lapping circles. Each circle is a different color.
    g.FillEllipse(trnsRedBrush, x1, y1, 2*triHeight, 2*triHeight);
    g.FillEllipse(trnsGreenBrush, x1 + triBase/2, y1 + triHeight,
        2*triHeight, 2*triHeight);
    g.FillEllipse(trnsBlueBrush, x1 + triBase, y1, 2*triHeight, 2*triHeight);
}

这将绘制3个重叠的圆,但我认为没有任何一个会有“透明点”。 - Greg Sansom
我知道。你和我对这个问题的理解不同;我不知道他真正想要什么。 - egrunin
@egrunin和@Greg - Greg是正确的,也许我表达这个问题有误(我一直在搜索但没有找到解决方案的指针),我真的很想创建一个没有下面内容的透明点。 - Nicholas Murray
所以你基本上想在那个位置使图像透明?这意味着你会看到图像后面的任何东西(如果有的话)? - Mike Park
@climbage - 是的,我正在尝试创建一个谜题Web应用程序,在其中可以通过使图像的某些部分透明来创建形状。 - Nicholas Murray

1
你需要使用RadialGradientBrush:
RadialGradientBrush b = new RadialGradientBrush();
b.GradientOrigin = new Point(0.5, 0.5);
b.Center = new Point(0.5, 0.5);
b.RadiusX = 0.5;
b.RadiusY = 0.5;
b.GradientStops.Add(new GradientStop(Colors.Transparent,0));
b.GradientStops.Add(new GradientStop(Colors.Transparent,0.25));
b.GradientStops.Add(new GradientStop(Colors.Tomato, 0.25));
g.FillEllipse(b, 50, 50, 200, 200);

alt text


这是WPF的一部分吗?我能把它用作网站上对图像的预处理的一部分吗? - Nicholas Murray
是的,这是WPF的一部分。如果您用我上面的代码替换g.FillEllipse()行,则SourceImage.Save()应该将图像保存到磁盘,以便准备上传到Web。 - Greg Sansom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接