如何将文本转换为 SVG 路径?

     2023-03-15     28

关键词:

【中文标题】如何将文本转换为 SVG 路径?【英文标题】:How to convert text to SVG paths? 【发布时间】:2011-12-06 05:29:23 【问题描述】:

我在 ttf 文件中有一个字体,并且想要生成 SVG,并将文本转换为路径。我不需要图像(因此使用 imagettftext 或 Image Magick 字体渲染功能是不够的),我需要可以放大和缩小的形状,我想丢失有关使用的字体的信息并且不想在其中引用它SVG 文件(因此这里不能使用字体声明)。有可能吗?

【问题讨论】:

【参考方案1】:

一种解决方法是使用inkscape(在将SVG 文档保存到file.svg 后通过exec 左右执行它)。在 inkscape 0.49+ 中,you can 只需传递 --export-to-svg--export-text-to-path,如下所示:

$ inkscape file_text.svg --export-text-to-path --export-plain-svg file_shapes.svg

在 inkscape

$ inkscape --with-gui --verb EditSelectAll --verb ObjectToPath --verb FileSave \
           --verb FileQuit file.svg

【讨论】:

我为 SVG 字体处理附加了 PHP 类。您可以在此处查看示例输出:lukasz.logo.pdev.cksk.com/…【参考方案2】:

如果你能得到一个 svgfont,那么你就有了使用字形路径渲染它的所有信息(将你需要的所有字形路径数据复制粘贴到任意数量的路径元素并应用翻转变换和缩放它到你需要的任何大小)。 Batik 有一个名为 ttf2svg 的工具,它可以为您提供 svgfont 输出。还有其他的,例如fontforge。

不确定是否有任何纯命令行工具可以直接生成这样的 svg,但 Inkscape 解决方案应该完全符合您的要求。

【讨论】:

【参考方案3】:

我创建了自己的类来处理 SVG 字体文件并将文本转换为字形。使用示例:

include "SVGFont.php";
$svgFont = new SVGFont();
$svgFont->load("/path/to/font.svg");
$result = $svgFont->textToPaths("Simple text", 20);

示例结果:

<g transform="scale(0.009765625) translate(0, 0)"><path transform="translate(0,0) rotate(180) scale(-1, 1)" d="M92 471l183 16q13 -110 60.5 -180.5t147.5 -114t225 -43.5q111 0 196 33t126.5 90.5t41.5 125.5q0 69 -40 120.5t-132 86.5q-59 23 -261 71.5t-283 91.5q-105 55 -156.5 136.5t-51.5 182.5q0 111 63 207.5t184 146.5t269 50q163 0 287.5 -52.5t191.5 -154.5t72 -231 l-186 -14q-15 139 -101.5 210t-255.5 71q-176 0 -256.5 -64.5t-80.5 -155.5q0 -79 57 -130q56 -51 292.5 -104.5t324.5 -93.5q128 -59 189 -149.5t61 -208.5q0 -117 -67 -220.5t-192.5 -161t-282.5 -57.5q-199 0 -333.5 58t-211 174.5t-80.5 263.5z" /><path transform="translate(1366,0) rotate(180) scale(-1, 1)" d="M136 0v1062h180v-1062h-180zM136 1259v207h180v-207h-180z" /><path transform="translate(1821,0) rotate(180) scale(-1, 1)" d="M135 0v1062h161v-149q50 78 133 125.5t189 47.5q118 0 193.5 -49t106.5 -137q126 186 328 186q158 0 243 -87.5t85 -269.5v-729h-179v669q0 108 -17.5 155.5t-63.5 76.5t-108 29q-112 0 -186 -74.5t-74 -238.5v-617h-180v690q0 120 -44 180t-144 60q-76 0 -140.5 -40 t-93.5 -117t-29 -222v-551h-180z" /><path transform="translate(3527,0) rotate(180) scale(-1, 1)" d="M135 -407v1469h164v-138q58 81 131 121.5t177 40.5q136 0 240 -70t157 -197.5t53 -279.5q0 -163 -58.5 -293.5t-170 -200t-234.5 -69.5q-90 0 -161.5 38t-117.5 96v-517h-180zM298 525q0 -205 83 -303t201 -98q120 0 205.5 101.5t85.5 314.5q0 203 -83.5 304t-199.5 101 q-115 0 -203.5 -107.5t-88.5 -312.5z" /><path transform="translate(4666,0) rotate(180) scale(-1, 1)" d="M131 0v1466h180v-1466h-180z" /><path transform="translate(5121,0) rotate(180) scale(-1, 1)" d="M75 522q0 268 138 416t358 148q213 0 348 -145t135 -408q0 -16 -1 -48h-792q10 -175 99 -268t222 -93q99 0 169 52t111 166l186 -23q-44 -163 -163 -253t-304 -90q-233 0 -369.5 143.5t-136.5 402.5zM271 633h593q-12 134 -68 201q-86 104 -223 104q-124 0 -208.5 -83 t-93.5 -222z" /><path transform="translate(6260,0) rotate(180) scale(-1, 1)" d="" /><path transform="translate(6829,0) rotate(180) scale(-1, 1)" d="M36 922v140h132v263l179 108v-371h181v-140h-181v-621q0 -77 9.5 -99t31 -35t61.5 -13q30 0 79 7l26 -159q-76 -16 -136 -16q-98 0 -152 31t-76 81.5t-22 212.5v611h-132z" /><path transform="translate(7398,0) rotate(180) scale(-1, 1)" d="M75 522q0 268 138 416t358 148q213 0 348 -145t135 -408q0 -16 -1 -48h-792q10 -175 99 -268t222 -93q99 0 169 52t111 166l186 -23q-44 -163 -163 -253t-304 -90q-233 0 -369.5 143.5t-136.5 402.5zM271 633h593q-12 134 -68 201q-86 104 -223 104q-124 0 -208.5 -83 t-93.5 -222z" /><path transform="translate(8537,0) rotate(180) scale(-1, 1)" d="M15 0l388 552l-359 510h225l163 -249q46 -71 74 -119q44 66 81 117l179 251h215l-367 -500l395 -562h-221l-218 330l-58 89l-279 -419h-218z" /><path transform="translate(9561,0) rotate(180) scale(-1, 1)" d="M36 922v140h132v263l179 108v-371h181v-140h-181v-621q0 -77 9.5 -99t31 -35t61.5 -13q30 0 79 7l26 -159q-76 -16 -136 -16q-98 0 -152 31t-76 81.5t-22 212.5v611h-132z" /></g>

我的班级代码:

<?php

/**
 * This class represents SVG pa
 * @author Łukasz Ledóchowski lukasz@ledochowski.pl
 * @version 0.1
 */
class SVGFont 

    protected $id = '';
    protected $horizAdvX = 0;
    protected $unitsPerEm = 0;
    protected $ascent = 0;
    protected $descent = 0;
    protected $glyphs = array();

    /**
     * Function takes UTF-8 encoded string and returns unicode number for every character.
     * Copied somewhere from internet, thanks.
     */
    function utf8ToUnicode( $str ) 
        $unicode = array();
        $values = array();
        $lookingFor = 1;

        for ($i = 0; $i < strlen( $str ); $i++ ) 
            $thisValue = ord( $str[ $i ] );
            if ( $thisValue < 128 ) $unicode[] = $thisValue;
            else 
                if ( count( $values ) == 0 ) $lookingFor = ( $thisValue < 224 ) ? 2 : 3;
                $values[] = $thisValue;
                if ( count( $values ) == $lookingFor ) 
                    $number = ( $lookingFor == 3 ) ?
                        ( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ):
                        ( ( $values[0] % 32 ) * 64 ) + ( $values[1] % 64 );

                    $unicode[] = $number;
                    $values = array();
                    $lookingFor = 1;
                
            
        

        return $unicode;
    

    /**
     * Function takes path to SVG font (local path) and processes its xml
     * to get path representation of every character and additional
     * font parameters
     */
    public function load($filename) 
        $this->glyphs = array();
        $z = new XMLReader;
        $z->open($filename);

        // move to the first <product /> node
        while ($z->read()) 
            $name = $z->name;

            if ($z->nodeType == XMLReader::ELEMENT) 
                if ($name == 'font') 
                    $this->id = $z->getAttribute('id');
                    $this->horizAdvX = $z->getAttribute('horiz-adv-x');
                

                if ($name == 'font-face') 
                    $this->unitsPerEm = $z->getAttribute('units-per-em');
                    $this->ascent = $z->getAttribute('ascent');
                    $this->descent = $z->getAttribute('descent');
                

                if ($name == 'glyph') 
                    $unicode = $z->getAttribute('unicode');
                    $unicode = $this->utf8ToUnicode($unicode);
                    $unicode = $unicode[0];

                    $this->glyphs[$unicode] = new stdClass();
                    $this->glyphs[$unicode]->horizAdvX = $z->getAttribute('horiz-adv-x');
                    if (empty($this->glyphs[$unicode]->horizAdvX)) 
                        $this->glyphs[$unicode]->horizAdvX = $this->horizAdvX;
                    
                    $this->glyphs[$unicode]->d = $z->getAttribute('d');
                
            
        

    

    /**
     * Function takes UTF-8 encoded string and size, returns xml for SVG paths representing this string.
     * @param string $text UTF-8 encoded text
     * @param int $asize size of requested text
     * @return string xml for text converted into SVG paths
     */
    public function textToPaths($text, $asize) 
        $lines = explode("\n", $text);
        $result = "";
        $horizAdvY = 0;
        foreach($lines as $text) 
            $text = $this->utf8ToUnicode($text);
            $size =  ((float)$asize) / $this->unitsPerEm;
            $result .= "<g transform=\"scale($size) translate(0, $horizAdvY)\">";
            $horizAdvX = 0;
            for($i = 0; $i < count($text); $i++) 
                $letter = $text[$i];
                $result .= "<path transform=\"translate($horizAdvX,$horizAdvY) rotate(180) scale(-1, 1)\" d=\"$this->glyphs[$letter]->d\" />";
                $horizAdvX += $this->glyphs[$letter]->horizAdvX;
            
            $result .= "</g>";
            $horizAdvY += $this->ascent + $this->descent;
        

        return $result;
    

【讨论】:

这不支持连字吗? @CorySimmons:我不需要支持连字。如果连字是 svg 文件中的单独字符,它应该可以工作。这次我不是字体专家:)【参考方案4】:

我刚刚根据您的库编写了一个 PHP 库,用于处理字体数据(来自 SVG 文件)并对其进行任何类型的转换。您可以在 GitHub 上尝试一下:

https://github.com/kartsims/easysvg

使用示例:

require 'easySVG.php';
$svg = new EasySVG();
$svg->setFont("paris-bold-webfont.svg", 100, "#000000");
$svg->addText("Simple text display");
$svg->addAttribute("width", "800px");
$svg->addAttribute("height", "100px");
echo $svg->asXML();

SVG 数据操作示例:

$def = 'YOUR SVG DEFINITION HERE';
$easySVG = new EasySVG();
// rotate by 40°
$rotated_def = $easySVG->defRotate($def, 40)
// rotate by 40° with center at (200,100)
$rotated_def2 = $easySVG->defRotate($def, 40, 200, 100)
// scale transform : width*4
$scaled_def = $easySVG->defScale($def, 4)

【讨论】:

我认为这个库比公认的答案更好。 一些吸气剂会很好......比如获取创建的分组路径的宽度和高度。 我知道这对 SVG 没有多大意义,但是像 getBBox 之类的 php 库......会很好。【参考方案5】:

运行 Inkscape。输入您的文字。单击菜单 > 路径 > 对象到路径。

单击另存为...并选择纯 SVG 格式。

【讨论】:

感谢这个完美的作品,并且可以免费下载inkscape。我的字体在 Figma 中不起作用,我不得不这样做。对于任何感兴趣的人来说,该字体都是legothick :)【参考方案6】:

在 Boxy SVG 3.28 中 选择文本然后进入菜单:形状 > 形状到路径

文本将转换,每个字形现在都是来自给定字体/字体的可编辑矢量形状

David Spector 的 Inkscape 答案是我最近使用的答案

【讨论】:

将轮廓路径转换为 ​​svg 路径

】将轮廓路径转换为​​svg路径【英文标题】:Convertcontourpathstosvgpaths【发布时间】:2017-08-2320:10:38【问题描述】:我正在使用带有python的openCV从图像中提取轮廓。现在我需要将这些轮廓路径(列表)导出为svg路径。我怎样才能... 查看详情

将 Google 字体路径转换为 ​​SVG 路径

】将Google字体路径转换为​​SVG路径【英文标题】:ConvertGooglefontspathtoSVGpath【发布时间】:2020-11-0211:37:14【问题描述】:我正在尝试按照https://github.com/danmarshall/google-font-to-svg-path的示例将Google字体创建为svg。我的代码如下:opent... 查看详情

计算 SVG 路径

...aphaeljs.com/australia.html。但我需要坐标为SVG路径标准格式。如何将图像映射转换为SVG坐标?干杯安东尼【问题讨论】:显然你因为没有提出问题而被 查看详情

仅在将鼠标悬停在圆圈上时才沿文本路径为 SVG 文本设置动画

】仅在将鼠标悬停在圆圈上时才沿文本路径为SVG文本设置动画【英文标题】:AnimateSVGtextalongatext-pathonlywhenhoveringoveracircle【发布时间】:2018-06-2908:56:11【问题描述】:我想将动画从HTML移动到css。仅当您将鼠标悬停在&lt;circleid=&... 查看详情

坎夫 |将 SVG 转换为 Canvas 以输出为图像

...。test111.js在其中创建div#forSVG和svg#svg(加上圆圈、路径、文本)。<html>< 查看详情

以编程方式将 SVG 形状转换为路径(lineto、moveto)

】以编程方式将SVG形状转换为路径(lineto、moveto)【英文标题】:ProgrammaticallyconvertSVGshapestopaths(lineto,moveto)【发布时间】:2013-02-1815:57:03【问题描述】:我有一个来自Inkscape、Illustrator或任何其他应用程序的SVG文件。我想将形状... 查看详情

d3.js:将 SVG 地理路径转换为画布

】d3.js:将SVG地理路径转换为画布【英文标题】:d3.js:convertSVGgeo-pathtocanvas【发布时间】:2021-04-1009:00:40【问题描述】:我是D3的新手,刚刚编写了一个小代码来在地图上显示点转换:StaticImage我从一个大约100点的小样本开始,效... 查看详情

将具有混合(固定和百分比)值的 CSS 剪辑路径转换为 ​​SVG 剪辑路径

】将具有混合(固定和百分比)值的CSS剪辑路径转换为​​SVG剪辑路径【英文标题】:TransformCSSclip-pathwithmixed(fixedandpercentage)valuestoSVGclip-path【发布时间】:2019-05-1313:20:47【问题描述】:我有一张使用clip-path的带有剪角渐变的卡... 查看详情

如何将matplotlib图的输出作为svg?(代码片段)

我需要获取matplotlib图的输出并将其转换为我可以在激光切割机上使用的SVG路径。importmatplotlib.pyplotaspltimportnumpyasnpx=np.arange(0,100,0.00001)y=x*np.sin(2*pi*x)plt.plot(y)plt.show()例如,下面您会看到一个波形。我希望能够将此波形输出或保存... 查看详情

D3、SVG 和 textPath:如何将文本下移?

】D3、SVG和textPath:如何将文本下移?【英文标题】:D3,SVGandtextPath:Howtomovethetextdown?【发布时间】:2013-04-2104:52:36【问题描述】:我有一个图表,其中包含一些使用textPath沿着其中一条路径编写的文本。但是,我的问题是:我需要... 查看详情

如何平滑手绘的 SVG 路径?

】如何平滑手绘的SVG路径?【英文标题】:HowtosmoothafreehanddrawnSVGpath?【发布时间】:2011-10-0101:55:50【问题描述】:我正在寻找一种解决方案,将用户手绘的SVG路径(由许多aufLineTo段组成)转换为更平滑的路径。首选语言是JavaScrip... 查看详情

如何在不改变坐标的情况下转换(旋转)svg文本元素?

】如何在不改变坐标的情况下转换(旋转)svg文本元素?【英文标题】:Howtotransform(rotate)svgtextelementwithoutchangingcoordinates?【发布时间】:2018-03-3017:07:34【问题描述】:我是这个d3.js的新手。在这里,我尝试使用d3.v3.js库绘制条形... 查看详情

如何将 .svg 文件转换为字体? [关闭]

】如何将.svg文件转换为字体?[关闭]【英文标题】:HowcanIconvert.svgfilestoafont?[closed]【发布时间】:2012-10-2800:56:54【问题描述】:如何将.svg文件转换为字体?有没有API或可编程的方法?【问题讨论】:你有什么样的SVG文件?您是... 查看详情

如何将 fabric.js 对象转换为 SVG

】如何将fabric.js对象转换为SVG【英文标题】:Howtoconvertfabric.jsObjecttoSVG【发布时间】:2021-11-0815:33:15【问题描述】:我知道可以将整个cavas转换为SVG。但是是否可以将单独的对象(如Path、Line、Rect等)转换为SVG,包括应用于这些... 查看详情

如何将 PNG 图像转换为 SVG? [关闭]

】如何将PNG图像转换为SVG?[关闭]【英文标题】:HowtoconvertaPNGimagetoaSVG?[closed]【发布时间】:2010-12-2402:24:16【问题描述】:如何将PNG图像转换为SVG?【问题讨论】:通过一些应用程序或通过操作系统命令?如果通过操作系统,请... 查看详情

如何制作图标字体(如何将svg转换为css可用的图标字体)

转自: 如何制作图标字体(如何将svg转换为css可用的图标字体)具体描述在项目开发当中,我们常常遇到需要将获取到的svg转换为,css可用的图标字体,那么具体该如何进行操作呢具体操作登录icomoon点击右上角登录旁边的ic... 查看详情

如何制作图标字体(如何将svg转换为css可用的图标字体)

转自: 如何制作图标字体(如何将svg转换为css可用的图标字体)具体描述在项目开发当中,我们常常遇到需要将获取到的svg转换为,css可用的图标字体,那么具体该如何进行操作呢具体操作登录icomoon点击右上角登录旁边的ic... 查看详情

如何使用 ImageMagick 将 SVG 转换为 PNG?

】如何使用ImageMagick将SVG转换为PNG?【英文标题】:HowtoconvertaSVGtoaPNGwithImageMagick?【发布时间】:2012-04-0820:19:25【问题描述】:我有一个定义为16x16大小的SVG文件。当我使用ImageMagick的转换程序将其转换为PNG时,我得到一个16x16像... 查看详情