使用.Net Graphicspath进行信封扭曲

3

我正在寻找实现在.NET中对GraphicsPath进行形状变形的最佳方法。 我想要实现的结果是将文本弯曲成上下弯曲,向左或向右扇形,并像波浪一样呈现。所有这些都可以在Adobe Illustrator中使用envelope distort功能实现。

我考虑过自己编写一种方法来使用预定义网格和点映射系统来转换点。不过,似乎已经有一些可用于如何实现这一点的算法或示例了吗?

2个回答

4

我想跟进一下我之前发布的帖子。我已经找到了另外几种方法来完成我原来在这篇帖子中想做的事情。首先,GraphicsPath有一个不错的warp()方法,可以将任何路径扭曲成矩形的4个点。使用这个想法,您可以完成以下操作。

向右扭曲

这是将弯曲文字应用于相同warp路径的结果:

文字弯曲

只需在warp()方法中设置矩形的4个点即可实现这个经典的星球大战文字扭曲效果

星球大战文字扭曲

将相同的warp应用于向上弧形的路径。

向下弧线与星球大战扭曲

我的结论是,许多扭曲可以通过首先在路径上键入(例如弧形或波浪形),然后在GraphicsPath中应用warp()方法来完成。

更新

我终于在将近两年后想出了一个真正的解决方案。我在我的博客上发布了一个详细的解释和代码。 在这里阅读


如果您发布与您的效果相关的代码,那将是非常棒的! - Cyril Gandon
@CyrilGandon 我刚刚链接到了我写的关于使用 C# 和 GraphicsPath 类进行信封扭曲的博客文章。 - Particleman
请注意,GeographicsPath.Warp在Linux上尚未正常工作。https://github.com/dotnet/corefx/issues/33528 - Serge Pavlov

3
这里有一些我们使用的验证码生成器中的方法,可能会帮助你找到正确的方向:
    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);
    }

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