web-dev-qa-db-ja.com

InkscapeでのSVGマトリックス変換のフラット化

Windows 8 JavaScriptゲームで使用するために変更を加えているInkscapeで作成された無料のクリップアートSVGファイルがあります。次のように、周囲のグループにマトリックス変換が適用されたパスの多数のインスタンスが含まれています。

<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
    <path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />
</g>

アニメーション中のブラウザの作業を減らすために、Inkscapeのパスに事前に適用して、その変換をフラット化したいと考えています。ただし、6つのマトリックス値をInkscapeのA B C D E Fパラメータにプラグインして適用すると、IE10エンジンの動作とはまったく異なる回転とスケーリングがパスに与えられます。

6つの値が正しくマッピングされていることを何度も確認しました。何が悪いのですか?

編集:OK、IE10とInkscapeからのスクリーンショットの前と後を示します。 IE10の場合、SVGは空のHTMLドキュメントの本文の中に直接存在します(Firefoxでのレンダリングはまったく同じです)。 Inkscapeでは、パス要素のみを含む「前」のSVGファイルを開き、パスを選択し、6つの行列変換値をオブジェクト>変換>行列にプラグインしました。マトリックスについてはほとんど知りませんが、ブラウザと同じようにこれらの変換を事前に適用できるようにしたいのですが、Inkscapeに違いがある理由を理解するのが理想的です。ありがとう。

IE10 path onlyIE10 path with transformInkscape path onlyInkscape path with transform

39
Tom Hall

簡潔な答え

Inkscapeで変換行列のパラメーターを入力するときは、「現在の行列を編集する」がチェックされていることを確認してください。オブジェクトに新しい変換行列を適用すると、実際にはこの新しい行列にオブジェクトの既存の変換行列が乗算されるため、代わりに編集してください。
enter image description here

長い答え

すべてを自分で再計算する方法。

まず、変換行列を少し理解してみましょう。変換行列は、ベクトルにアフィン変換(直線を保持する変換)を適用するための迅速で賢いツールです。
したがって、ベクトル(たとえば、2d座標)と変換行列があり、その2つを掛け合わせると、変換行列で定義された変換が適用された変換座標になります。
transformation matrix
計算中x'およびy'は次のように行われます:

x' = a*x + c*y + e 
y' = b*x + d*y + f

次に、svgフォーマットについて少し理解する必要があります。
w3c svg spec によると、matrix変換はこれらの6つのパラメーター(a、b、c、d、e、f)を引数として正確に受け取ります。
したがって、あなたの例から、

<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">

次の変換行列パラメーターがあります。

a=0.443
b=0.896
c=-0.896
d=0.443
e=589.739
f=-373.223

ここで、次の座標の例がある場合:x=27, y=-9、以前に定義した次のような変換行列を使用して変換できます。

x' = a*x + c*y + e 
x' = 0.443*27 + -0.896*-9 + 589.739
x' = 609.764

y' = b*x + d*y + f
y' = 0.896*27 + 0.443*-9 -373.223
y' = −353.018

きちんとね?詳細はこちら こちら

しかし、それだけではありません。また、svgパスデータについても理解する必要があります。
w3c svg path dspecification によると、パスデータの各文字は命令を表します。また、命令に続く各数値ペアは座標値を表します。

あなたの例から、私たちは次のパスを持っています:

<path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />

ここで、このパスオブジェクトが1つの絶対moveto命令を使用していることがわかります(大文字[〜#〜] m [〜#〜])、相対smooth curveto 3次ベジェ曲線(小文字s)、相対lineto命令(小文字l)、および別の親類smooth curvetoキュービックベジエ曲線命令、それに続くclosepath命令(小文字z)。

M486,313absolute moveto x = 486、y = 313に変換されます
s27-9,43-29は、負の数が負の場合は不要なので一部のコマが省略されるため、少し複雑です。マイナス記号はコマとして機能します-とにかく、relative smoothに変換されますx = 27、y = -9、x = 43、y = -29へのベジェ曲線(1つの宛先点と1つの制御点)
等々。

それでは、svgグループに変換行列を適用して削除するにはどうすればよいでしょうか。そのようです:

// we read the transformation matrix params
// <g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
a=0.443
b=0.896
c=-0.896
d=0.443
e=589.739
f=-373.223

// we read the path data, and transform each instruction    
// <path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />

M486,313に移動

x' = a*x + c*y + e = a*486 + c*313 + e = 524.589
y' = b*x + d*y + f = b*486 + d*313 + f = 200.892

命令への移動は今M524.589,200.892

S27-9,43-29-曲線を滑らかにし、各座標に対して同じプロセスを繰り返しますが、ef(変換パラメータ)を0に設定します。これは、絶対ではなく相対命令だからです。
今です
s20.025,20.205,45.033,25.680999999999997

l26,4,1,23-22,5
となります
l7.934000000000001,25.067999999999998、-20.165,11.085、-14.226、-17.497

s-25-6-48-3
となります
s-5.698999999999999、-25.058000000000003、-18.576、-44.337

そしてzは残りますz

したがって、結果の変換されたパスは次のようになります。

<path d="M524.589,200.892s20.025,20.205,45.033,25.680999999999997l7.934000000000001,25.067999999999998,-20.165,11.085,-14.226,-17.497s-5.698999999999999,-25.058000000000003,-18.576,-44.337z" />

これがあなたにとって理にかなっているといいのですが。

56
ArtBIT

パスを選択してからパス->ユニオン(CTRL ++)を使用して、座標をベイクできます。お役に立てれば

20
parameciostudio

所定の位置に貼り付けが役立ちます:

  1. グループをダブルクリック Inkscapeで入力します。
  2. すべて選択 Ctrl + Aを押してグループのコンテンツを、そしてコピー Ctrl + Cを押してグループのコンテンツを選択します。
  3. 外側をダブルクリックグループを離れるグループ。
  4. Edit> Paste In Place(Ctrl + Alt + V)–この時点で、貼り付けたオブジェクトにグループ変換が適用されます。
  5. Groupオブジェクトを再度(Ctrl + G)
  6. 新しいグループを元のグループと同じ深さに移動し、元のグループを削除にします。 (これはおそらくXMLエディター、Ctrl + Shift + Xを使用すると簡単です。)
15
andraaspar

@andraasparの回答に続いて、グループ解除(Ctrl-U)とグループ化(Ctrl-G)を試すこともできます。それは私のために働いた。

11
btel

すべての情報をArtBITに感謝します! 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)
1
kartsims