mirror of
https://github.com/Chouchen/svgToImage.git
synced 2020-02-03 22:08:42 +01:00
ajout de commentaires pour y voir plus clair
tentative d'ajout de courbes de Bézier tentative d'amélioration de rotation (il y a tjs un décalage)
This commit is contained in:
parent
a4b06813a2
commit
ae129cf977
289
svgtoimage.php
289
svgtoimage.php
@ -2,33 +2,35 @@
|
|||||||
// TODO
|
// TODO
|
||||||
// ajouter header thanks to http://fr.php.net/manual/fr/function.image-type-to-mime-type.php
|
// ajouter header thanks to http://fr.php.net/manual/fr/function.image-type-to-mime-type.php
|
||||||
// prendre en compte l'opacité grâce à imagecolorallocatealpha ?
|
// prendre en compte l'opacité grâce à imagecolorallocatealpha ?
|
||||||
// conversion des couleurs "black" , "blue", etc en #000 etc.
|
|
||||||
// stroke-width pour tous \o/
|
// stroke-width pour tous \o/
|
||||||
// pour les rectangles avec point ou tiret http://fr.php.net/manual/fr/function.imagesetstyle.php
|
// pour les rectangles avec point ou tiret http://fr.php.net/manual/fr/function.imagesetstyle.php
|
||||||
|
// ajout de title
|
||||||
|
|
||||||
include 'log.php';
|
include 'log.php';
|
||||||
|
|
||||||
class SVGTOIMAGE{
|
class SVGTOIMAGE{
|
||||||
|
|
||||||
protected $_svg;
|
|
||||||
protected $_svgXML;
|
protected $_svgXML;
|
||||||
protected $_image;
|
protected $_image;
|
||||||
protected $_format;
|
|
||||||
protected $_log;
|
protected $_log;
|
||||||
protected $_x;
|
protected $_x;
|
||||||
protected $_y;
|
protected $_y;
|
||||||
protected $_width;
|
protected $_width;
|
||||||
protected $_height;
|
protected $_height;
|
||||||
protected $_showDesc = false;
|
protected $_showDesc = false;
|
||||||
|
protected $_desc;
|
||||||
private $transparentColor = array(0,0,255);
|
private $transparentColor = array(0,0,255);
|
||||||
public $_debug = true;
|
public $_debug = true;
|
||||||
|
|
||||||
//const TIRET = array($red, $red, $red, $red, $red, IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT);
|
/* array of color names => hex color
|
||||||
|
because some svg creator uses them
|
||||||
|
*/
|
||||||
private $colors = array(
|
private $colors = array(
|
||||||
'black' => '#000000',
|
'black' => '#000000',
|
||||||
'red' => '#FF0000',
|
'red' => '#FF0000',
|
||||||
'white' => '#FFFFFF',
|
'white' => '#FFFFFF',
|
||||||
'turquoise' => '#00FFFF',
|
'turquoise' => '#00FFFF',
|
||||||
|
'grey' => '#CCCCCC',
|
||||||
'light grey' => '#C0C0C0',
|
'light grey' => '#C0C0C0',
|
||||||
'light blue' => '#0000FF',
|
'light blue' => '#0000FF',
|
||||||
'dark grey' => '#808080',
|
'dark grey' => '#808080',
|
||||||
@ -45,27 +47,46 @@ class SVGTOIMAGE{
|
|||||||
'grass green' => '#408080',
|
'grass green' => '#408080',
|
||||||
);
|
);
|
||||||
|
|
||||||
public function __construct($svg, $format = 'png'){
|
/*
|
||||||
|
* constructor
|
||||||
|
* parse the svg with simplexml
|
||||||
|
*/
|
||||||
|
public function __construct($svg){
|
||||||
if($this->_debug) $this->_log = new Log('log.dat');
|
if($this->_debug) $this->_log = new Log('log.dat');
|
||||||
$this->_svg = $svg;
|
|
||||||
if($this->_debug) $this->_log->message('Ouverture du fichier contentant : '.$svg);
|
if($this->_debug) $this->_log->message('Ouverture du fichier contentant : '.$svg);
|
||||||
$this->_svgXML = simplexml_load_string($this->_svg);
|
$this->_svgXML = simplexml_load_string($svg);
|
||||||
$this->_format = $format;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Construct with a file
|
||||||
|
* @param : string path to the file
|
||||||
|
* @return : instance of this class
|
||||||
|
*/
|
||||||
public static function load($file){
|
public static function load($file){
|
||||||
$svg = file_get_contents($file);
|
$svg = file_get_contents($file);
|
||||||
return new SVGTOIMAGE($svg);
|
return new SVGTOIMAGE($svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Construct with a string
|
||||||
|
* @param : string <svg>...</svg>
|
||||||
|
* @return : instance of this class
|
||||||
|
*/
|
||||||
public static function parse($xml){
|
public static function parse($xml){
|
||||||
return new SVGTOIMAGE($xml);
|
return new SVGTOIMAGE($xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroy the GD Image when finished
|
||||||
|
*/
|
||||||
public function __destruct(){
|
public function __destruct(){
|
||||||
imagedestroy($this->_image);
|
imagedestroy($this->_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setter - option : show the description from the svg into the image if present
|
||||||
|
* @param boolean
|
||||||
|
*/
|
||||||
public function setShowDesc($showDesc = true){
|
public function setShowDesc($showDesc = true){
|
||||||
if(is_bool($showDesc)){
|
if(is_bool($showDesc)){
|
||||||
if($this->_debug) $this->_log->message('Passage de showDesc en '.$showDesc);
|
if($this->_debug) $this->_log->message('Passage de showDesc en '.$showDesc);
|
||||||
@ -75,6 +96,10 @@ class SVGTOIMAGE{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setter - option : origin of the final image from the svg (default : 0)
|
||||||
|
* @param int
|
||||||
|
*/
|
||||||
public function setX($x){
|
public function setX($x){
|
||||||
if(is_int($x)){
|
if(is_int($x)){
|
||||||
if($this->_debug) $this->_log->message('Passage de x en '.$x);
|
if($this->_debug) $this->_log->message('Passage de x en '.$x);
|
||||||
@ -84,6 +109,10 @@ class SVGTOIMAGE{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setter - option : origin of the final image from the svg (default : 0)
|
||||||
|
* @param int
|
||||||
|
*/
|
||||||
public function setY($y){
|
public function setY($y){
|
||||||
if(is_int($y)){
|
if(is_int($y)){
|
||||||
if($this->_debug) $this->_log->message('Passage de y en '.$y);
|
if($this->_debug) $this->_log->message('Passage de y en '.$y);
|
||||||
@ -93,6 +122,10 @@ class SVGTOIMAGE{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setter - option : width of the final image (default : svg width)
|
||||||
|
* @param int
|
||||||
|
*/
|
||||||
public function setWidth($width){
|
public function setWidth($width){
|
||||||
if(is_int($width)){
|
if(is_int($width)){
|
||||||
if($this->_debug) $this->_log->message('Passage de width en '.$width);
|
if($this->_debug) $this->_log->message('Passage de width en '.$width);
|
||||||
@ -102,6 +135,10 @@ class SVGTOIMAGE{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setter - option : height of the final image (default : svg height)
|
||||||
|
* @param int
|
||||||
|
*/
|
||||||
public function setHeight($height){
|
public function setHeight($height){
|
||||||
if(is_int($height)){
|
if(is_int($height)){
|
||||||
if($this->_debug) $this->_log->message('Passage de height en '.$height);
|
if($this->_debug) $this->_log->message('Passage de height en '.$height);
|
||||||
@ -120,15 +157,24 @@ class SVGTOIMAGE{
|
|||||||
return $imageSize;
|
return $imageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @return int final image width
|
||||||
|
*/
|
||||||
private function _getImageWidth(){
|
private function _getImageWidth(){
|
||||||
return isset($this->_width) ? $this->_width : $this->_svgXML->attributes()->width;
|
return isset($this->_width) ? $this->_width : $this->_svgXML->attributes()->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @return int final image height
|
||||||
|
*/
|
||||||
private function _getImageHeight(){
|
private function _getImageHeight(){
|
||||||
return isset($this->_height) ? $this->_height : $this->_svgXML->attributes()->height;
|
return isset($this->_height) ? $this->_height : $this->_svgXML->attributes()->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param string Color code (ie: #CCC , #FE4323, etc...)
|
||||||
|
* @return array with R | G | B
|
||||||
|
*/
|
||||||
private function _parseColor($colorCode){
|
private function _parseColor($colorCode){
|
||||||
if(strlen($colorCode) == 7){
|
if(strlen($colorCode) == 7){
|
||||||
if($this->_debug) $this->_log->message('Parse Color '.$colorCode);
|
if($this->_debug) $this->_log->message('Parse Color '.$colorCode);
|
||||||
@ -150,8 +196,13 @@ class SVGTOIMAGE{
|
|||||||
return array(0,0,0);
|
return array(0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate color to the final image thanks to _parseColor (check if the color isn't spelled directly 'black')
|
||||||
|
* @param string color code
|
||||||
|
* @return imageallocate on the image
|
||||||
|
*/
|
||||||
private function _allocateColor($color){
|
private function _allocateColor($color){
|
||||||
if($color != '' && array_key_exists($color, $this->colors)){
|
if($color != '' && array_key_exists(strtolower($color), $this->colors)){
|
||||||
$arrayColor = $this->_parseColor($this->colors[$color]);
|
$arrayColor = $this->_parseColor($this->colors[$color]);
|
||||||
}else{
|
}else{
|
||||||
$arrayColor = $this->_parseColor($color);
|
$arrayColor = $this->_parseColor($color);
|
||||||
@ -159,12 +210,18 @@ class SVGTOIMAGE{
|
|||||||
return imagecolorallocate( $this->_image, $arrayColor[0], $arrayColor[1], $arrayColor[2] );
|
return imagecolorallocate( $this->_image, $arrayColor[0], $arrayColor[1], $arrayColor[2] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add the given image from svg to the final image
|
||||||
|
* @param simpleXMLElement
|
||||||
|
* @return imagecopy
|
||||||
|
*/
|
||||||
private function _parseImage($imageNode){
|
private function _parseImage($imageNode){
|
||||||
$x = 0;
|
$x = 0;
|
||||||
$y = 0;
|
$y = 0;
|
||||||
$width = 0;
|
$width = 0;
|
||||||
$height = 0;
|
$height = 0;
|
||||||
$href = '';
|
$href = '';
|
||||||
|
$transform = '';
|
||||||
$r = 0;
|
$r = 0;
|
||||||
foreach($imageNode->attributes() as $name => $value){
|
foreach($imageNode->attributes() as $name => $value){
|
||||||
switch($name){
|
switch($name){
|
||||||
@ -174,10 +231,23 @@ class SVGTOIMAGE{
|
|||||||
case 'height': $height = $value; break;
|
case 'height': $height = $value; break;
|
||||||
case 'href':
|
case 'href':
|
||||||
case 'xlink:href':$href = $value; break;
|
case 'xlink:href':$href = $value; break;
|
||||||
case 'r' : $r = $value; break;
|
//case 'r' : $r = $value; break; // no !
|
||||||
|
case 'transform': $transform = $value;
|
||||||
case 'style' : if(strripos($value, 'display: none') || strripos($value, 'display:none')) return; break;
|
case 'style' : if(strripos($value, 'display: none') || strripos($value, 'display:none')) return; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if($transform != ''){
|
||||||
|
$transforms = split('[()]', $transform);
|
||||||
|
$nb = count($transforms);
|
||||||
|
for($i = 0; $i < $nb; $i++){
|
||||||
|
// rotation
|
||||||
|
if($transforms[$i] == 'rotate'){
|
||||||
|
$rotinfo = $transforms[$i+1];
|
||||||
|
$rotinfo = explode(' ', $rotinfo);
|
||||||
|
$r = $rotinfo[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if($width == 0 || $height == 0 || $href == '')
|
if($width == 0 || $height == 0 || $href == '')
|
||||||
return;
|
return;
|
||||||
if($this->_debug) $this->_log->message('Image - x : '.$x.' - y : '.$y.' - largeur : '.$width.' - longueur : '.$height.' - url : '.$href.' - angle : '.$r);
|
if($this->_debug) $this->_log->message('Image - x : '.$x.' - y : '.$y.' - largeur : '.$width.' - longueur : '.$height.' - url : '.$href.' - angle : '.$r);
|
||||||
@ -208,15 +278,27 @@ class SVGTOIMAGE{
|
|||||||
imagecolortransparent($newImage, $blue);
|
imagecolortransparent($newImage, $blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
imagecopy($this->_image,$newImage,$x,$y,0,0,imagesx($newImage) , imagesy($newImage));
|
imagecopy($this->_image,$newImage,$x,$y,0,0, $width , $height);
|
||||||
|
//imagecopy($this->_image,$newImage,$x,$y,0,0,imagesx($newImage) , imagesy($newImage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the given SVG xml is W3C valid
|
||||||
|
* DEPRECATED
|
||||||
|
* @param string <svg>...</svg>
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
private function _pathIsW3C($path){
|
private function _pathIsW3C($path){
|
||||||
if(strripos($path, ','))
|
if(strripos($path, ','))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* small function to find int into a string - works like java parseint
|
||||||
|
* @param string containing numbers
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
private function _parseInt($string){
|
private function _parseInt($string){
|
||||||
if(preg_match('/(\d+)/', $string, $array)) {
|
if(preg_match('/(\d+)/', $string, $array)) {
|
||||||
return $array[1];
|
return $array[1];
|
||||||
@ -225,6 +307,12 @@ class SVGTOIMAGE{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add a line to the final image
|
||||||
|
* @param $x1, $y1, $x2, $y2 int position of segment
|
||||||
|
* @param imagecolorallocate color (via _allocatecolor !)
|
||||||
|
* @return imageline
|
||||||
|
*/
|
||||||
private function _drawLine($x1, $y1, $x2, $y2, $color){
|
private function _drawLine($x1, $y1, $x2, $y2, $color){
|
||||||
if(!imageline( $this->_image , $x1, $y1, $x2, $y2, $color )){
|
if(!imageline( $this->_image , $x1, $y1, $x2, $y2, $color )){
|
||||||
if($this->_debug) $this->_log->error('Chemin erroné : '.$x1.' - '.$y1.' - '.$x2.' - '.$y2);
|
if($this->_debug) $this->_log->error('Chemin erroné : '.$x1.' - '.$y1.' - '.$x2.' - '.$y2);
|
||||||
@ -233,9 +321,12 @@ class SVGTOIMAGE{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add path/lineS/polyline whatever you name it.
|
||||||
|
* @param simpleXMLElement
|
||||||
|
* @return lines on the final image via _drawLine
|
||||||
|
*/
|
||||||
private function _parsePath($pathNode){
|
private function _parsePath($pathNode){
|
||||||
// <path d="M50,50 A30,30 0 0,1 35,20 L100,100 M110,110 L100,0" style="stroke:#660000; fill:none;"/>
|
|
||||||
//<path d="M20 150 L150 350 Z" />
|
|
||||||
// imagesetbrush
|
// imagesetbrush
|
||||||
// imagesetstyle (pour dotted, dashed etc)
|
// imagesetstyle (pour dotted, dashed etc)
|
||||||
$path = '';
|
$path = '';
|
||||||
@ -244,14 +335,14 @@ class SVGTOIMAGE{
|
|||||||
$stroke = '';
|
$stroke = '';
|
||||||
foreach($pathNode->attributes() as $name=>$value){
|
foreach($pathNode->attributes() as $name=>$value){
|
||||||
switch($name){
|
switch($name){
|
||||||
case 'd': $path = $value; break;
|
case 'd': case 'points': $path = $value; break;
|
||||||
case 'stroke': $stroke = $value; break;
|
case 'stroke': $stroke = $value; break;
|
||||||
case 'fill': $fill = ($value == 'none') ? '' : $value; break;
|
case 'fill': $fill = ($value == 'none') ? '' : $value; break;
|
||||||
case 'stroke-width' : $strokeWidth = $value; break;
|
case 'stroke-width' : $strokeWidth = $value; break;
|
||||||
case 'style' : if(strripos($value, 'display: none') || strripos($value, 'display:none')) return; break;
|
case 'style' : if(strripos($value, 'display: none') || strripos($value, 'display:none')) return; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(substr($path, 0,1) != 'M'){
|
if(substr($path, 0,1) != 'M' && !is_numeric(substr($path, 0,1))){
|
||||||
if($this->_debug) $this->_log->error('Mauvais path rencontré : '.$path);
|
if($this->_debug) $this->_log->error('Mauvais path rencontré : '.$path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -302,6 +393,40 @@ class SVGTOIMAGE{
|
|||||||
$lastOpe = 'V';
|
$lastOpe = 'V';
|
||||||
$i++;
|
$i++;
|
||||||
|
|
||||||
|
}elseif(substr($pathArray[$i], 0, 1) == 'C'){
|
||||||
|
|
||||||
|
$control1x = $this->_parseInt($pathArray[$i]);
|
||||||
|
$control1y = $this->_parseInt($pathArray[$i+1]);
|
||||||
|
$control2x = $this->_parseInt($pathArray[$i+2]);
|
||||||
|
$control2y = $this->_parseInt($pathArray[$i+3]);
|
||||||
|
$newX = $this->_parseInt($pathArray[$i+4]);
|
||||||
|
$newY = $this->_parseInt($pathArray[$i+5]);
|
||||||
|
|
||||||
|
// Algorithme de http://www.dreamstube.com/post/Bezier-Curves-In-PHP!.aspx ne fonctionne pas !
|
||||||
|
$cx=3*($control1x-$lastX);
|
||||||
|
$bx=3*($control2x-$control1x)-$cx;
|
||||||
|
$ax=$newX-$lastX-$cx-$bx;
|
||||||
|
|
||||||
|
$cy=3*($control1y-$lastY);
|
||||||
|
$by=3*($control2y-$control1y)-$cy;
|
||||||
|
$ay=$newY-$lastY-$cy-$by;
|
||||||
|
if($this->_debug) $this->_log->message('ax : '.$ax.', ay : '.$ay);
|
||||||
|
$function_x='('.$ax.')*$t*$t*$t+('.$bx.')*$t*$t+('.$cx.')*$t+'.$lastX;
|
||||||
|
$function_y='('.$ay.')*$t*$t*$t+('.$by.')*$t*$t+('.$cy.')*$t+'.$lastY;
|
||||||
|
$function_z=2;
|
||||||
|
$j=0;
|
||||||
|
for($t=0; $t<1; $t+=.01)
|
||||||
|
{
|
||||||
|
eval('$x_points[$j]=1*'.$function_x.';');
|
||||||
|
eval('$y_points[$j]=1*'.$function_y.';');
|
||||||
|
eval('$z_points[$j]=1*'.$function_z.';');
|
||||||
|
if($this->_debug) $this->_log->message('cx : '.$x_points[$j].', cy : '.$y_points[$j]*(-1).' d: '.$z_points[$j]);
|
||||||
|
imagearc($this->_image, $x_points[$j]+$this->_getImageWidth()/2, ($y_points[$j]*(-1))+$this->_getImageHeight()/2, $z_points[$j], $z_points[$j], 0, 360, $colorStroke);
|
||||||
|
$j++;
|
||||||
|
}
|
||||||
|
$lastX = $newX;
|
||||||
|
$lastY = $newY;
|
||||||
|
$i=$i+6;
|
||||||
}elseif(is_numeric(substr($pathArray[$i], 0, 1))){
|
}elseif(is_numeric(substr($pathArray[$i], 0, 1))){
|
||||||
switch($lastOpe){
|
switch($lastOpe){
|
||||||
case 'L':
|
case 'L':
|
||||||
@ -310,6 +435,7 @@ class SVGTOIMAGE{
|
|||||||
$this->_drawLine($lastX , $lastY , $newX , $newY , $colorStroke);
|
$this->_drawLine($lastX , $lastY , $newX , $newY , $colorStroke);
|
||||||
$lastX = $newX;
|
$lastX = $newX;
|
||||||
$lastY = $newY;
|
$lastY = $newY;
|
||||||
|
$i=$i+2;
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
$newX = $this->_parseInt($pathArray[$i]);
|
$newX = $this->_parseInt($pathArray[$i]);
|
||||||
@ -327,9 +453,12 @@ class SVGTOIMAGE{
|
|||||||
if($this->_debug) $this->_log->error('2 bouclages dans une boucle');
|
if($this->_debug) $this->_log->error('2 bouclages dans une boucle');
|
||||||
$i++;
|
$i++;
|
||||||
break;
|
break;
|
||||||
default :
|
default : //polyline
|
||||||
if($this->_debug) $this->_log->error('last opé inconnue '.$lastOpe);
|
if($this->_debug) $this->_log->error('last opé inconnue '.$lastOpe);
|
||||||
$i++;
|
$lastX = $this->_parseInt($pathArray[$i]);
|
||||||
|
$lastY = $this->_parseInt($pathArray[$i+1]);
|
||||||
|
$lastOpe = 'L';
|
||||||
|
$i=$i+2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,7 +467,7 @@ class SVGTOIMAGE{
|
|||||||
$lastOpe = 'Z'; //utile?
|
$lastOpe = 'Z'; //utile?
|
||||||
$i++;
|
$i++;
|
||||||
}else
|
}else
|
||||||
$i++; // au cas où.
|
$i++; // au cas où pour éviter une boucle infinie.
|
||||||
if($this->_debug) $this->_log->message('counter :'.$i);
|
if($this->_debug) $this->_log->message('counter :'.$i);
|
||||||
}
|
}
|
||||||
imagecolordeallocate( $this->_image, $colorStroke);
|
imagecolordeallocate( $this->_image, $colorStroke);
|
||||||
@ -346,6 +475,11 @@ class SVGTOIMAGE{
|
|||||||
imagesetthickness ( $this->_image , 1 );
|
imagesetthickness ( $this->_image , 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add a circle in the final image
|
||||||
|
* @param SimpleXMLElement
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
private function _parseCircle($circleNode){
|
private function _parseCircle($circleNode){
|
||||||
$x = 0;
|
$x = 0;
|
||||||
$y = 0;
|
$y = 0;
|
||||||
@ -386,8 +520,12 @@ class SVGTOIMAGE{
|
|||||||
imagesetthickness ( $this->_image , 1 );
|
imagesetthickness ( $this->_image , 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add a rectangle to the final image
|
||||||
|
* @param simpleXMLElement
|
||||||
|
* @return a nice rectangle !
|
||||||
|
*/
|
||||||
private function _parseRectangle($rectNode){
|
private function _parseRectangle($rectNode){
|
||||||
//<rect x="168" y="275" width="52" height="70" r="0" rx="0" ry="0" fill="none" stroke="#000" stroke-dasharray="8,3" transform="rotate(21.91207728 194 310)" style="opacity: 1; display: none; " opacity="1"></rect>
|
|
||||||
$x = 0;
|
$x = 0;
|
||||||
$y = 0;
|
$y = 0;
|
||||||
$width = 0;
|
$width = 0;
|
||||||
@ -398,7 +536,6 @@ class SVGTOIMAGE{
|
|||||||
$strokeWidth = 1;
|
$strokeWidth = 1;
|
||||||
foreach($rectNode->attributes() as $name => $value){
|
foreach($rectNode->attributes() as $name => $value){
|
||||||
switch($name){
|
switch($name){
|
||||||
// imagesetthickness ( resource $image , int $thickness )
|
|
||||||
// imagesetstyle (pour dotted, dashed etc)
|
// imagesetstyle (pour dotted, dashed etc)
|
||||||
case 'x': $x = $value; break;
|
case 'x': $x = $value; break;
|
||||||
case 'y': $y = $value; break;
|
case 'y': $y = $value; break;
|
||||||
@ -419,7 +556,7 @@ class SVGTOIMAGE{
|
|||||||
if($this->_debug && !$thickness) $this->_log->error('Erreur dans la mise en place de l\'épaisseur du trait');
|
if($this->_debug && !$thickness) $this->_log->error('Erreur dans la mise en place de l\'épaisseur du trait');
|
||||||
if($this->_debug) $this->_log->message('Rectangle - x : '.$x.' - y : '.$y.' - width : '.$width.' - height : '.$height.' - fill : '.$colorFill[0].'-'.$colorFill[1].'-'.$colorFill[2].' - stroke : '.$colorStroke[0].'-'.$colorStroke[1].'-'.$colorStroke[2]);
|
if($this->_debug) $this->_log->message('Rectangle - x : '.$x.' - y : '.$y.' - width : '.$width.' - height : '.$height.' - fill : '.$colorFill[0].'-'.$colorFill[1].'-'.$colorFill[2].' - stroke : '.$colorStroke[0].'-'.$colorStroke[1].'-'.$colorStroke[2]);
|
||||||
if($fill == ''){
|
if($fill == ''){
|
||||||
imagerectangle($this->_image , $x , $y , $x+$width , $y+$height, $colorStroke); //resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color
|
imagerectangle($this->_image , $x , $y , $x+$width , $y+$height, $colorStroke);
|
||||||
}else{
|
}else{
|
||||||
imagefilledrectangle ($this->_image , $x , $y , $x+$width , $y+$height, $colorFill );
|
imagefilledrectangle ($this->_image , $x , $y , $x+$width , $y+$height, $colorFill );
|
||||||
}
|
}
|
||||||
@ -428,32 +565,110 @@ class SVGTOIMAGE{
|
|||||||
imagesetthickness ( $this->_image , 1 );
|
imagesetthickness ( $this->_image , 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add a polygon in the final image
|
||||||
|
* @param simpleXMLElement
|
||||||
|
* @return po-po-po-polygon !
|
||||||
|
*/
|
||||||
|
private function _parsePolygon($polyNode){
|
||||||
|
$points = '';
|
||||||
|
$fill = '';
|
||||||
|
$stroke = '';
|
||||||
|
$strokeWidth = 1;
|
||||||
|
foreach($polyNode->attributes() as $name => $value){
|
||||||
|
switch($name){
|
||||||
|
// imagesetstyle (pour dotted, dashed etc)
|
||||||
|
case 'points' : $points = $value; break;
|
||||||
|
case 'fill': $fill = ($value == 'none') ? '' : $value; break;
|
||||||
|
case 'stroke': $stroke = $value; break;
|
||||||
|
case 'stroke-width' : $strokeWidth = $value; break;
|
||||||
|
case 'style' : if(strripos($value, 'display: none') || strripos($value, 'display:none')) return; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($points == '')
|
||||||
|
return;
|
||||||
|
$pointArray = split('[ ,]', $points);
|
||||||
|
$colorStroke = $this->_allocateColor((string)$stroke);
|
||||||
|
$colorFill = $this->_allocateColor((string)$fill);
|
||||||
|
$thickness = imagesetthickness( $this->_image , (int)$strokeWidth );
|
||||||
|
if($this->_debug && !$thickness) $this->_log->error('Erreur dans la mise en place de l\'épaisseur du trait');
|
||||||
|
|
||||||
|
if($fill == ''){
|
||||||
|
imagepolygon ( $this->_image , $pointArray , count($pointArray)/2 , $colorStroke );
|
||||||
|
}else{
|
||||||
|
imagefilledpolygon ($this->_image , $pointArray , count($pointArray)/2 , $colorFill );
|
||||||
|
}
|
||||||
|
imagecolordeallocate($this->_image,$colorStroke);
|
||||||
|
imagecolordeallocate($this->_image,$colorFill);
|
||||||
|
imagesetthickness ( $this->_image , 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add the description text in the final image
|
||||||
|
* @param string the description
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
private function _parseDescription($desc){
|
private function _parseDescription($desc){
|
||||||
if($this->_debug) $this->_log->message('Ajout de la description : '.$desc);
|
if($this->_debug) $this->_log->message('Ajout de la description : '.$desc);
|
||||||
return imagestring ( $this->_image , 2, 10, $this->_getImageHeight()-20, $desc , imagecolorallocate($this->_image, 255, 255, 255));
|
return imagestring ( $this->_image , 2, 10, $this->_getImageHeight()-20, $desc , imagecolorallocate($this->_image, 255, 255, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toImage(){
|
/*
|
||||||
//$test = Imagick::__construct('http://labs.shikiryu.com/experimental-cut/images/pieces/2.png');
|
* ignore group for the moment
|
||||||
|
* acts like ungrouped
|
||||||
|
*/
|
||||||
|
private function _parseGroup($groupNode){
|
||||||
|
foreach($groupNode->children() as $element){
|
||||||
|
$this->_chooseParse($element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* select what to parse
|
||||||
|
* @param simpleXMLElement
|
||||||
|
* @return the selected function
|
||||||
|
*/
|
||||||
|
private function _chooseParse($element){
|
||||||
|
if($element->getName() == 'image')
|
||||||
|
$this->_parseImage($element);
|
||||||
|
if($element->getName() == 'circle')
|
||||||
|
$this->_parseCircle($element);
|
||||||
|
if($element->getName() == 'rect')
|
||||||
|
$this->_parseRectangle($element);
|
||||||
|
if($element->getName() == 'path')
|
||||||
|
$this->_parsePath($element);
|
||||||
|
if($element->getName() == 'polygon')
|
||||||
|
$this->_parsePolygon($element);
|
||||||
|
if($element->getName() == 'polyline')
|
||||||
|
$this->_parsePath($element);
|
||||||
|
if($element->getName() == 'title')
|
||||||
|
$this->_parseTitle($element);
|
||||||
|
if($element->getName() == 'desc' && $this->_showDesc)
|
||||||
|
$this->_desc = $element;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parse everything, main function
|
||||||
|
* @param string format of the ouput 'png' 'gif' jpg'
|
||||||
|
* @param string path where you want to save the file (with the final name), null will just show the image but not saved on server
|
||||||
|
* @return the image
|
||||||
|
*/
|
||||||
|
public function toImage($format = 'png', $path = null){
|
||||||
$writeDesc = null;
|
$writeDesc = null;
|
||||||
$this->_image = imagecreatetruecolor($this->_getImageWidth(), $this->_getImageHeight());
|
$this->_image = imagecreatetruecolor($this->_getImageWidth(), $this->_getImageHeight());
|
||||||
imagealphablending($this->_image, true);
|
imagealphablending($this->_image, true);
|
||||||
//imageantialias($this->_image, true); // On ne peut pas gérer l'épaisseur des traits si l'antialiasing est activé... lol ?
|
//imageantialias($this->_image, true); // On ne peut pas gérer l'épaisseur des traits si l'antialiasing est activé... lol ?
|
||||||
foreach($this->_svgXML->children() as $element){
|
foreach($this->_svgXML->children() as $element){
|
||||||
if($element->getName() == 'image')
|
$this->_chooseParse($element);
|
||||||
$this->_parseImage($element);
|
|
||||||
if($element->getName() == 'circle')
|
|
||||||
$this->_parseCircle($element);
|
|
||||||
if($element->getName() == 'rect')
|
|
||||||
$this->_parseRectangle($element);
|
|
||||||
if($element->getName() == 'path')
|
|
||||||
$this->_parsePath($element);
|
|
||||||
if($element->getName() == 'desc' && $this->_showDesc)
|
|
||||||
$writeDesc = $element;
|
|
||||||
}
|
}
|
||||||
if($writeDesc) $this->_parseDescription($writeDesc);
|
if($this->_showDesc && $this->_desc != null) $this->_parseDescription($this->_desc);
|
||||||
//imagefilter ( $this->_image , IMG_FILTER_SMOOTH, 6);
|
//imagefilter ( $this->_image , IMG_FILTER_SMOOTH, 6);
|
||||||
return imagepng($this->_image);
|
switch($format){
|
||||||
|
case 'png' :
|
||||||
|
default :
|
||||||
|
//header('Content-type: image/png');
|
||||||
|
return imagepng($this->_image, $path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
18
test.php
18
test.php
@ -3,6 +3,20 @@ include 'svgtoimage.php';
|
|||||||
/*
|
/*
|
||||||
<image x="184" y="286" width="10" height="10" preserveAspectRatio="none" href="imageurl4.png" style="cursor: pointer; opacity: 1; display: none; " opacity="1"></image>
|
<image x="184" y="286" width="10" height="10" preserveAspectRatio="none" href="imageurl4.png" style="cursor: pointer; opacity: 1; display: none; " opacity="1"></image>
|
||||||
<image x="204" y="286" width="10" height="10" preserveAspectRatio="none" href="imageurl5.png" style="cursor: pointer; opacity: 1; display: none; " opacity="1"></image>
|
<image x="204" y="286" width="10" height="10" preserveAspectRatio="none" href="imageurl5.png" style="cursor: pointer; opacity: 1; display: none; " opacity="1"></image>
|
||||||
|
<path d="M153 334
|
||||||
|
C153 334 151 334 151 334
|
||||||
|
C151 339 153 344 156 344
|
||||||
|
C164 344 171 339 171 334
|
||||||
|
C171 322 164 314 156 314
|
||||||
|
C142 314 131 322 131 334
|
||||||
|
C131 350 142 364 156 364
|
||||||
|
C175 364 191 350 191 334
|
||||||
|
C191 311 175 294 156 294
|
||||||
|
C131 294 111 311 111 334
|
||||||
|
C111 361 131 384 156 384
|
||||||
|
C186 384 211 361 211 334
|
||||||
|
C211 300 186 274 156 274"
|
||||||
|
style="fill:white;stroke:red;stroke-width:2"/>
|
||||||
*/
|
*/
|
||||||
$svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="512">
|
$svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="512">
|
||||||
<desc>Created with Raphael</desc>
|
<desc>Created with Raphael</desc>
|
||||||
@ -13,6 +27,10 @@ $svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height
|
|||||||
<circle cx="100" cy="50" r="40" stroke="#000" stroke-width="2" fill="none"/>
|
<circle cx="100" cy="50" r="40" stroke="#000" stroke-width="2" fill="none"/>
|
||||||
<image x="170" y="277" width="48" height="66" preserveAspectRatio="none" href="http://labs.shikiryu.com/experimental-cut/images/pieces/1.png" style="cursor: move; opacity: 1; " r="90" opacity="1" transform="rotate(21.91207728 194 310)"></image>
|
<image x="170" y="277" width="48" height="66" preserveAspectRatio="none" href="http://labs.shikiryu.com/experimental-cut/images/pieces/1.png" style="cursor: move; opacity: 1; " r="90" opacity="1" transform="rotate(21.91207728 194 310)"></image>
|
||||||
<path d="M50 50 V150 H150 L200 50 Z" stroke="red" stroke-width="3" />
|
<path d="M50 50 V150 H150 L200 50 Z" stroke="red" stroke-width="3" />
|
||||||
|
<polygon points="60,150 160,60 260,150 210,250 110,250" stroke="red" stroke-width="3"/>
|
||||||
|
|
||||||
|
<polyline stroke="gray" stroke-width="5"
|
||||||
|
points="80,250 80,280 60,280 60,310 80,310 80,340 40,340 40,370 80,370 80,400 20,400 20,430 80,430" />
|
||||||
</svg>';
|
</svg>';
|
||||||
|
|
||||||
$svgtoimage = SVGTOIMAGE::parse($svg);
|
$svgtoimage = SVGTOIMAGE::parse($svg);
|
||||||
|
Loading…
Reference in New Issue
Block a user