Искажение конверта с помощью .Net Graphicspath - PullRequest
3 голосов
/ 26 января 2012

Я пытаюсь найти наилучший способ выполнить деформацию GraphicsPath в .net для конкретной формы. В результате я пытаюсь добиться деформации текста, который будет изгибаться вверх, вниз, вращаться влево, вправо и что-то вроде волны. Все это может быть достигнуто в Adobe Illustrator с помощью функции искажения конверта.

Я подумал о том, чтобы применить свой собственный метод для этого с использованием некоторой предопределенной системы отображения сетки и точек для преобразования точек. Тем не менее, похоже, что будут некоторые алгоритмы или примеры того, как сделать это уже доступным?

Ответы [ 2 ]

4 голосов
/ 25 сентября 2012

Я хотел бы продолжить этот пост, который я сделал некоторое время назад. Я разработал несколько других способов выполнить то, что я хотел сделать первоначально в этом посте. Прежде всего, у GraphicsPath есть хороший метод warp (), который выполняет именно это, деформируя любой путь в 4 точки прямоугольника. Используя эту идею, вы можете сделать это ниже.

Warping up to the right

Здесь та же самая деформация, примененная к пути с выгнутым текстом

Text Arched Up Warp

Это классическая деформация текста звездных войн, просто установив 4 точки прямоугольника в методе warp () Star Wars Text Warp

Тот же перекос, примененный к изогнутой траектории.

Arched Down with a Star Wars Warp

Я пришел к выводу, что множество перекосов можно выполнить, сначала напечатав путь, такой как арка или волна, а затем применив метод warp () в GraphicsPath.

Обновлен

Я наконец-то нашел способ найти реальное решение для этого почти через 2 года. Я разместил подробное объяснение с кодом в моем блоге. Прочитайте это здесь

3 голосов
/ 26 января 2012

Вот несколько методов из используемого нами генератора капчи, которые могут направить вас в правильном направлении:

    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);
    }
...