.Net Graphicspath 的包络失真

发布于 2024-12-29 03:48:58 字数 201 浏览 3 评论 0原文

我正在尝试找出将 .net 中的 GraphicsPath 扭曲为特定形状的最佳方法。我想要实现的结果是将文本扭曲为向上、向下、向左、向右扇形以及类似波浪的形状。所有这些都可以在 Adob​​e Illustrator 中使用包络扭曲功能来实现。

我已经考虑过使用一些预定义的网格和点映射系统来实现我自己的方法来转换点。然而,似乎已经有一些关于如何做到这一点的算法或示例?

I'm trying to figure out the best way to accomplish warping a GraphicsPath in .net to a specific shape. The result I'm trying to achieve is warping text to curve up, down, fan left, right, and things like a wave. All of these can be achieved in Adobe Illustrator using the envelope distort feature.

I have considered rolling my own method of doing this using some of predefined grid and point mapping system to transform points. However, it seems like there would be some algorithms or samples as to how to do this already available?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柏林苍穹下 2025-01-05 03:48:58

我想跟进我不久前发表的这篇文章。我已经想出了一些其他方法来完成我在这篇文章中最初想做的事情。首先,GraphicsPath 有一个很好的 warp() 方法,它可以将任何路径扭曲成矩形的 4 个点。使用这个想法你可以完成下面的任务。

向右扭曲

这是应用于文本向上拱起的路径的相同扭曲

Text Arched Up Warp

这是经典的星球大战文本扭曲,只需在 warp() 方法中设置矩形的 4 个点即可
Star Wars Text Warp

相同的扭曲应用于拱形路径。

Arched Down with a Star Wars Warp

我得出的结论是,可以通过首先在这样的路径上键入来完成很多扭曲作为拱门或波浪,然后在 GraphicsPath 中应用 warp() 方法。

更新

近两年后,我终于开始真正想出一个真正的解决方案。我在我的博客上发布了带有代码的深入解释。 在此处阅读

I wanted to follow up to this post I made some time ago. I have had worked out a few other ways to accomplish what I wanted to do originally in this post. First off GraphicsPath has a nice warp() method which performs just that, warping any path into the 4 points of a rectangle. Using this idea you can accomplish this below.

Warping up to the right

Here is the same warp applied to a path with text arched up

Text Arched Up Warp

This is the classic star wars text warp by just setting the 4 points of the rectangle in the warp() method
Star Wars Text Warp

The same warp applied to a path that is arched up.

Arched Down with a Star Wars Warp

What I have concluded is a lot of warps can be accomplished by first typing on a path such as an arch or a wave, then applying the warp() method in a GraphicsPath.

Updated

I finally got around to actually coming up with a real solution to this almost 2 years later. I posted an in depth explanation with code on my blog. Read it here

╰沐子 2025-01-05 03:48:58

以下是我们使用的验证码生成器中的一些方法,它们可能会引导您走向正确的方向:

    internal static void DrawPhrase(
        this Graphics graphics, 
        int width, 
        int height, 
        string phrase)
    {
        graphics.FillRectangle(
            Brushes.White,
            0,
            0,
            width,
            height);

        using (var gp = new GraphicsPath())
        {
            gp.AddString(phrase,
                         FontFamily.GenericMonospace,
                         (int)FontStyle.Bold,
                         33f,
                         new Point(0,
                                   0),
                         StringFormat.GenericTypographic);

            using (var gpp = gp.Deform(width, height))
            {
                var bounds = gpp.GetBounds();
                var matrix = new Matrix();
                var x = (width - bounds.Width) / 2 - bounds.Left;
                var y = (height - bounds.Height) / 2 - bounds.Top;
                matrix.Translate(x,
                                 y);
                gpp.Transform(matrix);
                graphics.FillPath(Brushes.Black,
                                  gpp);
            }
        }

        graphics.Flush();
    }
    internal static GraphicsPath Deform(
        this GraphicsPath path, 
        int width, 
        int height)
    {
        var WarpFactor = 4;
        var xAmp = WarpFactor * width / 300d;
        var yAmp = WarpFactor * height / 50d;
        var xFreq = 2d * Math.PI / width;
        var yFreq = 2d * Math.PI / height;
        var deformed = new PointF[path.PathPoints.Length];
        var xSeed = rng.NextDouble() * 2 * Math.PI;
        var ySeed = rng.NextDouble() * 2 * Math.PI;
        var i = 0;
        foreach (var original in path.PathPoints)
        {
            var val = xFreq * original.X + yFreq * original.Y;
            var xOffset = (int)(xAmp * Math.Sin(val + xSeed));
            var yOffset = (int)(yAmp * Math.Sin(val + ySeed));
            deformed[i++] = new PointF(original.X + xOffset,
                                     original.Y + yOffset);
        }

        return new GraphicsPath(deformed,
                                path.PathTypes);
    }

Here's a couple of methods from a captcha generator we use that might steer you in the right direction:

    internal static void DrawPhrase(
        this Graphics graphics, 
        int width, 
        int height, 
        string phrase)
    {
        graphics.FillRectangle(
            Brushes.White,
            0,
            0,
            width,
            height);

        using (var gp = new GraphicsPath())
        {
            gp.AddString(phrase,
                         FontFamily.GenericMonospace,
                         (int)FontStyle.Bold,
                         33f,
                         new Point(0,
                                   0),
                         StringFormat.GenericTypographic);

            using (var gpp = gp.Deform(width, height))
            {
                var bounds = gpp.GetBounds();
                var matrix = new Matrix();
                var x = (width - bounds.Width) / 2 - bounds.Left;
                var y = (height - bounds.Height) / 2 - bounds.Top;
                matrix.Translate(x,
                                 y);
                gpp.Transform(matrix);
                graphics.FillPath(Brushes.Black,
                                  gpp);
            }
        }

        graphics.Flush();
    }
    internal static GraphicsPath Deform(
        this GraphicsPath path, 
        int width, 
        int height)
    {
        var WarpFactor = 4;
        var xAmp = WarpFactor * width / 300d;
        var yAmp = WarpFactor * height / 50d;
        var xFreq = 2d * Math.PI / width;
        var yFreq = 2d * Math.PI / height;
        var deformed = new PointF[path.PathPoints.Length];
        var xSeed = rng.NextDouble() * 2 * Math.PI;
        var ySeed = rng.NextDouble() * 2 * Math.PI;
        var i = 0;
        foreach (var original in path.PathPoints)
        {
            var val = xFreq * original.X + yFreq * original.Y;
            var xOffset = (int)(xAmp * Math.Sin(val + xSeed));
            var yOffset = (int)(yAmp * Math.Sin(val + ySeed));
            deformed[i++] = new PointF(original.X + xOffset,
                                     original.Y + yOffset);
        }

        return new GraphicsPath(deformed,
                                path.PathTypes);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文