2013-07-30 2 views
1

Я хочу повернуть SVG с помощью PHP.Как повернуть SVG по PHP

У меня есть файлы SVG и вы хотите повернуть их на PHP. Метод, который я нашел в Интернете, чтобы добавить что-то вроде

<g transform="translate(90) rotate(45 50 50)"> 

< внутри SVG >.

Для нелогич-, я хочу, чтобы преобразовать из:

<svg> <i-am-here+i-was-here>...</i-am-here+i-was-here> </svg> 

или

<svg> <g transform="i-have-transform-but-no-rotate"> <i-am-here+i-was-here>...</i-am-here+i-was-here> </g> </svg> 

To:

<svg> <g transform="svgrotate+old-transform"> <i-am-here+i-was-here>...</i-am-here+i-was-here> </g> </svg> 

, но теперь я не знаю, как этого добиться -

  1. добавить < г > внутри < > SVG и обернуть все старые внутренние узлы.

  2. если < г > уже оборачивать все внутренние узлы, а затем пропустить добавления нового < г > тег, но только повернуть его на новый уровень.

следующий возможный код svg перед вращением.

<?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
    <svg version="1.1" id="hello" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
     width="800px" height="700px" viewBox="0 0 800 700" enable-background="new 0 0 800 700" xml:space="preserve">   

    <g> 
     <path transform="rotate(-14.1173 121.2 96.1965)" id="svg_2" d="m128,25c9,14 9,204 -35,124c-44,-80 177,-52 120,-36c-57,16 -120,-77 -185,-79c-65,-2 288,166 169,128c-119,-38 -78,-151 -69,-137z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#3f007f" fill="#f4f438"/> 
     <path transform="rotate(152.959 126.708 104.715)" stroke="#3f007f" id="svg_3" d="m219.4411,94.86682c-50.99725,81.80002 -148.00278,74.4472 -190.13092,50.55057c-42.12811,-23.89664 5.54315,-43.19778 18.8468,-19.30115c13.30362,23.89664 81.48468,16.54382 108.64624,0.91913c27.16156,-15.62473 50.44287,-45.95508 54.87738,-56.06519c4.43463,-10.11011 58.75769,-57.90341 7.7605,23.89664z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#7fff00"/> 
    </g> 

    <path transform="rotate(9.48719 272.234 246.106)" id="svg_6" d="m214,78c0,-1 -108,23 -108,23c0,0 -85,108 23,85c108,-23 122,32 167,14c45,-18 -64,289 106,197c170,-92 -31,-310 -32,-310" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#3f007f" fill="#ffaad4"/> 
    <path d="m342,184c-7,-2 -12.98453,-3.08075 -18,-4c-5.98309,-1.0966 -11.53976,-2.46873 -19,-4c-5.87747,-1.20639 -13,-1 -18,-1c-7,0 -14.05798,-0.83221 -20,0c-7.20975,1.00977 -14.33942,4.12776 -23,8c-7.36008,3.29077 -14.23541,7.73578 -21,14c-5.1882,4.80443 -11.03857,10.11638 -16,17c-5.22981,7.25597 -7.48169,14.87997 -9,22c-1.47472,6.91557 -1.49489,14.02045 -1,20c0.50171,6.06204 3,11 5,16c2,5 3.72398,9.22272 7,13c3.70638,4.2735 5,5 6,5l1,0l3,-1" id="svg_1" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="none"/> 

    <g> 
     <path stroke="#000000" transform="rotate(-7.76776 324.596 222.303)" id="svg_4" d="m422.29062,129.05128c-126.20798,34.85936 91.52487,198.50475 -153.18372,103.60979c-244.70862,-94.89496 238.92807,178.17014 107.90298,114.26129c-131.02509,-63.90884 65.51254,-336.00563 -15.4147,-153.96223c-80.92725,182.04341 -141.62271,231.42751 -145.47639,168.48695c-3.85367,-62.94052 213.8792,-386.35803 113.68355,-284.68486c-100.19566,101.67317 67.43936,149.12065 111.75668,227.55424c44.31729,78.43359 -92.48828,66.81381 -114.64694,62.94052c-22.15866,-3.87326 184.97659,-174.29686 23.12207,-215.93445c-161.85452,-41.63758 -53.95151,-3.87326 -52.02466,114.26129c1.92682,118.13455 1.92682,118.13455 1.92682,118.13455" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#ff0000"/> 
     <path transform="rotate(20.3513 424.5 303.53)" stroke="#000000" id="svg_5" d="m368,255.68533l113,37.43481c0,0 13.37784,104.74188 -53.79596,69.57584c-67.17383,-35.16605 32.16373,-157.30188 -21.06299,-117.59828c-53.22668,39.7036 -53.22668,39.7036 -53.22668,39.7036" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#007fff"/> 
    </g> 

    <path transform="rotate(44.7788 399.595 115.757)" id="svg_8" d="m354,84c8,54 10,126 56,59c46,-67 42,-57 16,-76c-26,-19 -72,17 -72,17z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#3f007f" fill="#7f7f00"/> 

    </svg> 
+0

XML? Где находится XML? – Neal

+0

Итак, вы хотите переписать svg, чтобы весь контент был обернут тегом 'g' с преобразованием? – Ben

+0

Вы можете использовать [DOMDocument] (http://php.net/manual/en/class.domdocument.php) для загрузки и управления вашим svg-файлом или использования некоторых библиотек, упомянутых в этом вопросе SO ... http://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php – Ben

ответ

1

Я искал довольно долго и, наконец, положил это вместе. Надеюсь, поможет.

Вы можете использовать библиотеку SimpleXML для доступа к узлам по мере необходимости.

Мое решение работает, но может быть упрощено.

Во-первых, я добавил этот класс (found in the comments here):

class ExSimpleXMLElement extends SimpleXMLElement 
{ 


    public function _construct($xml){ 
     parent::_construct($xml); 
    } 

    /** 
    * Add SimpleXMLElement code into a SimpleXMLElement 
    * @param SimpleXMLElement $append 
    */ 
    public function appendXML($append) 
    { 
     if ($append) { 
      if (strlen(trim((string) $append))==0) { 
       $xml = $this->addChild($append->getName()); 
       foreach($append->children() as $child) { 
        $xml->appendXML($child); 
       } 
      } else { 
       $xml = $this->addChild($append->getName(), (string) $append); 
      }  
      foreach($append->attributes() as $n => $v) { 
       $xml->addAttribute($n, $v); 
      } 
     } 
    } 
} 

Просто включить, что до какого-либо кода.

//file 
$file = 'svg-nog.svg'; 

//http://www.webdeveloper.com/forum/showthread.php?165648-Editing-XML-using-PHP 
$xml = simplexml_load_file($file); //Load the File. 
$sxe = new EXSimpleXMLElement($xml->asXML()); //Load the child class (it will load the main one) 

// Get the parent node's childrens 
$nodeChildrens = $sxe->children(); 
//Check if there's more than one child and if there is more than one <g> tag 
if(count($nodeChildrens) > 1 and count($sxe->g) > 1){ 

//Add our Wrapper Node 
$g = $sxe->addChild("g"); 
//You can go ahead and add your desired transform code 
$g['transform'] = "rotate(90 600 600)"; 
//Set an ID so it's unique 
$g['id'] = "myWrapper"; 

$unsets = array(); 

//Loop through the children 
foreach ($nodeChildrens as $value) { 
      //Skip our wrapper element 
    if($value->attributes()->id == "myWrapper"){ 
     continue; 
    } 

      //Append the element to the wrapper 
      //Will recursively add elements as needed 
    $g->appendXML($value); 

    //Save a reference for the different elements we have 
    $unsets[] = $value->getName(); 
} 

//Loop through the old/loose elements and remove them 
foreach ($unsets as $name) { 
    $segarr = $sxe->{$name}; 

    $count = count($segarr); 

    $j = 0; 

    for ($i = 0; $i < $count; $i++) { 

     if ($segarr[$j]['id'] != 'myWrapper') { 
      unset($segarr[$j]); 
      $j = $j - 1; 
     } 
     $j = $j + 1; 
    } 
} 
} else { 
    //Just apply the transform 
    $sxe->g['transform'] = "rotate(90 600 600)"; 
     //Can also be done with: 
     //$sxe->g->addAttribute('transform', "rotate(90 600 600)"); 
} 

//Save 
$sxe->asXML('test.svg'); 

Это сработало для меня как для SVG, завернутых в тег, так и для тех, которые не были. Могут быть более простые способы сделать это, но это, безусловно, эффективно.

Еще одна вещь! Это может быть неверно, но когда я поворачивал SVG, они обычно были обрезаны. Таким образом, мне пришлось изменить основные атрибуты. Это означало замену высоты и ширины, а также перевод SVG для повторного центрирования.Здесь вы найдете:

//Set the vars of the primary attributes we want to edit 
$w = "width"; 
$h= "height"; 
$viewbox = "viewBox"; 
$bg = 'enable-background'; 

//Get SVG Width & Height 
$width = (string)$sxe->attributes()->$w; 
$height = (string)$sxe->attributes()->$h; 

//Get viewBox and background 
$sxe->attributes()->$viewbox = "0 0 " . str_replace('px', '', $height) . " " . str_replace('px', '', $width); 
$sxe->attributes()->$bg = "new 0 0 " . str_replace('px', '', $height) . " " . str_replace('px', '', $width); 

//Get the numerical values for width and height 
$rw = floatval(str_replace("px", "", $width)); 
$rh = floatval(str_replace("px", "", $height)); 

//Get the center point 
$rx = $rw/2; 
$ry = $rh/2; 

//Logic will determine the appropiate translate value for the svg so that it will center in the new viewbox 
if($rw < $rh){ 
    $trans = ($rw - $rh)/2; 
} 

if($rw > $rh){ 
    $trans = -1 * ($rh - $rw)/2; 
} 

//Swap width and height 
$oldW = (string)$sxe->attributes()->$w; 
$sxe->attributes()->$w = $height; 
$sxe->attributes()->$h = $oldW; 


// Get the parents node childrens 
$nodeChildrens = $sxe->children(); 

//If the transform attribute is set, this svg has already been rotated, as such, we'll just unset it 
if(isset($nodeChildrens->g->attributes()->transform)){ 
    unset($nodeChildrens->g->attributes()->transform); 
} else { 
    // Otherwise, we're going to add in the transform data for the rotation and re-centering. 
    $nodeChildrens->g->addAttribute('transform', "rotate(90 ".$rx." ".$ry.") translate(".$trans." ".$trans.")"); 
} 

//This next line will overwrite the original XML file with new data added 
$sxe->asXML("test.svg"); 

Вы можете заметить в нижней части, этот код также изменит процесс вращения.

Надеюсь, что это поможет!

Смежные вопросы