0

「ページ外」のコンテンツがSVGに含まれるまで、SVGをPNGに変換するためのスクリプトを作成しました。これは非常にうまく機能しています。

例えば:

「オフページ」のコンテンツを含むSVG

黒い線はうまく変換されますが、緑のボックスは完全に無視されます。一部のSVGファイルでは、コンテンツが完全にページから外れており、空のPNGファイルがレンダリングされます。

私の現在のコマンド:

convert -background none "$file" -trim -geometry $size "$target"

私はこの問題で少なくとも約500以上で変換している2k+SVGファイルを持っているので、画像を手動でページに移動することは実際にはオプションではありません。

編集ここにサンプルファイル へのリンクがあります。実際の図面は、ページの下部の左側に沿っています。

4

2 に答える 2

0

もちろん、「ページ外」のコンテンツは PNG では無視されます。SVG とは異なり、PNG ファイル形式は「オフページ」の概念を認識しません。

これは紙に印刷するのと似ています。プリンターは「オフページ」のコンテンツを表示することもできません。

探索するための 2 つのオプションがあります。両方の効果は、実際のページ サイズをより大きなサイズに変更することです。

  1. SVG をはるかに大きな PNG キャンバスにレンダリングし、その後余分なエッジを自動的にトリミングすることで、PNG の「オフページ」コンテンツを取得できる場合があります。(サンプルファイルがないため、自分でこれを試すことはできません。)

  2. 2 段階または 3 段階のプロセスで目的の結果を達成することを試みることができます。

    • 「ページ上の」すべてのオブジェクトが含まれるように、キャンバスを拡大して SVG を変更します。
    • 変更された SVG を PNG に変換します。
    • (オプション: PNG の端をトリミングします)。
于 2012-10-22T05:41:40.023 に答える
0

だから私はついにこれを機能させました。ImageMagick で直接行うことはできなかったので、実際の SVG データを操作することになりました。

まず、オブジェクトの境界を見つけます。PHP と simpleXml を使用して、SVG データを配列に変換し、簡単に操作/トラバースできるようにしました。

すべての座標が xy の形式になっているように見えるため、座標を数値に分割し、前の値より高い/低い場合に x / y の記録を切り替えます。

/** $line is a <g> object */
protected function _position($line, &$position) {
        if(empty($line['@d'])) {
            if(is_array($line)) {
                foreach($line as $l) {
                    self::_position($l, $position);
                }
                return;
            }
        }

        if(empty($position)) {
            $position = array(
                'min' => array(
                    'x' => null,
                    'y' => null
                ),
                'max' => array(
                    'x' => null,
                    'y' => null
                )
            );
        }

        foreach(array_filter(preg_split('/([a-z])/i', $line['@d'])) as $cord) {
            $coordinate = 'x';
            foreach(explode(' ', $cord) as $value) {
                if(empty($value)) {
                    continue;
                }

                if($position['min'][$coordinate] == null || $position['min'][$coordinate] > $value - 1) {
                    $position['min'][$coordinate] = $value;
                }

                if($position['max'][$coordinate] == null || $position['max'][$coordinate] < $value + 1) {
                    $position['max'][$coordinate] = $value;
                }

                $coordinate = ($coordinate != 'x') ? 'x' : 'y';
            }
        }
    }

最小/最大境界を取得したら、指定された x、y でオブジェクトを移動するプロパティtransformを見つけました。translateそのため、取得するだけ0 - $minで、そのままの状態に移動する00 - -100 - 10

<g>すべてのファイルには with 属性がないため、 with を単純に置き換えるだけです<g transform="translate($widthOffset, $heightOffset)">

ビューボックスのサイズも設定します。

$xml['svg']['@viewbox'] = sprintf('%s %s %s %s',
    $position['min']['x'],
    $position['min']['y'],
    ($position['max']['x'] - $position['min']['x']),
    ($position['max']['y'] - $position['min']['y'])
);

最後に、配列を XML に変換し、新しいデータをファイルに保存します。

于 2012-10-22T23:41:12.813 に答える