mirror of
https://github.com/Chouchen/svgToImage.git
synced 2020-02-03 22:08:42 +01:00
Optimisation du code Path |
Prise en compte d'un nouveau format Path | Changement du _parseInt afin de prendre en compte les int négatifs
This commit is contained in:
parent
94669b470f
commit
eb47804f61
@ -22,6 +22,18 @@ class SVGTOIMAGE{
|
||||
private $transparentColor = array(0,0,255);
|
||||
public $_debug = true; // change to false to stop debug mode
|
||||
|
||||
/*
|
||||
* array of path type
|
||||
*/
|
||||
private $pathType = array(
|
||||
'm' => 'MoveTo',
|
||||
'l' => 'LineTo',
|
||||
'h' => 'HorizontalLineTo',
|
||||
'v' => 'VerticalLineTo',
|
||||
'c' => 'CurveTo',
|
||||
'z' => 'EndingLine',
|
||||
);
|
||||
|
||||
/* array of color names => hex color
|
||||
because some svg creator uses them
|
||||
*/
|
||||
@ -53,7 +65,7 @@ class SVGTOIMAGE{
|
||||
*/
|
||||
public function __construct($svg){
|
||||
if($this->_debug) $this->_log = new Log('log.dat');
|
||||
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($svg);
|
||||
}
|
||||
|
||||
@ -318,8 +330,10 @@ class SVGTOIMAGE{
|
||||
* @return int
|
||||
*/
|
||||
private function _parseInt($string){
|
||||
if(preg_match('/(\d+)/', $string, $array)) {
|
||||
return $array[1];
|
||||
if(preg_match('/[-]?(\d+)/', $string, $array)) {
|
||||
//if(preg_match('/[-]?(\d+)/', $string, $array)) {
|
||||
return $array[0];
|
||||
//return $array[1];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@ -339,6 +353,30 @@ class SVGTOIMAGE{
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* add a curve to the final image
|
||||
* @param $startX, $startY, $control1X, $control1Y, $control2X, $control2Y, $endX, $endY int position of start, controls and end points
|
||||
* @param imagecolorallocate color (via _allocatecolor !)
|
||||
* @return lots of imagesetpixel
|
||||
* Algorithme de http://www.dreamstube.com/post/Bezier-Curves-In-PHP!.aspx
|
||||
*/
|
||||
private function _drawCurve($startX, $startY, $control1X, $control1Y, $control2X, $control2Y, $endX, $endY, $color){
|
||||
$cx=3*($control1X-$startX);
|
||||
$bx=3*($control2X-$control1X)-$cx;
|
||||
$ax=$endX-$startX-$cx-$bx;
|
||||
|
||||
$cy=3*($control1Y-$startY);
|
||||
$by=3*($control2Y-$control1Y)-$cy;
|
||||
$ay=$endY-$startY-$cy-$by;
|
||||
if($this->_debug) $this->_log->message('ax : '.$ax.', ay : '.$ay);
|
||||
for($t=0; $t<1; $t+=.01)
|
||||
{
|
||||
$xt = $ax * $t * $t * $t + $bx * $t * $t + $cx * $t + $startX;
|
||||
$yt = $ay * $t * $t * $t + $by * $t * $t + $cy * $t + $startY;
|
||||
imagesetpixel ( $this->_image , $xt , $yt , $color );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* add path/lineS/polyline whatever you name it.
|
||||
* @param simpleXMLElement
|
||||
@ -362,7 +400,7 @@ class SVGTOIMAGE{
|
||||
case 'style' : if(strripos($value, 'display: none') || strripos($value, 'display:none')) return; break;
|
||||
}
|
||||
}
|
||||
if(substr($path, 0,1) != 'M' && !is_numeric(substr($path, 0,1))){
|
||||
if(strtolower(substr($path, 0,1)) != 'm' && !is_numeric(substr($path, 0,1))){
|
||||
if($this->_debug) $this->_log->error('Mauvais path rencontré : '.$path);
|
||||
return;
|
||||
}
|
||||
@ -380,7 +418,31 @@ class SVGTOIMAGE{
|
||||
|
||||
$lastOpe = '';
|
||||
|
||||
$pathArray = split('[ ,]', $path); //explode(' ', $path);
|
||||
$pathArray = split('[ ,]', $path);
|
||||
|
||||
// Si le path est de format 'm 100 100 l 100 100 z' il faut recoller les morceaux
|
||||
if(array_key_exists($pathArray[0], $this->pathType)){
|
||||
reset($pathArray);
|
||||
$j = 0;
|
||||
do{
|
||||
if(array_key_exists($pathArray[$j], $this->pathType)){
|
||||
$pathArray[$j] = $pathArray[$j].$pathArray[$j+1];
|
||||
$pathArray[$j+1] = '~';
|
||||
$j++;
|
||||
$newNb = count($pathArray);
|
||||
for($k = $j; $k<=$newNb; $k++){
|
||||
$pathArray[$k] = $pathArray[$k+1];
|
||||
}
|
||||
}else{
|
||||
if($pathArray[$j] == '' || $pathArray[$j] == null)
|
||||
unset($pathArray[$j]);
|
||||
$j++;
|
||||
}
|
||||
}while(isset($pathArray[$j]));
|
||||
if($this->_debug) $this->_log->message('Path reconstruit ! '.implode(', ',$pathArray));
|
||||
}
|
||||
|
||||
|
||||
$nbArray = count($pathArray);
|
||||
$nbLine = (($nbArray-1)/2)-1;
|
||||
|
||||
@ -389,110 +451,63 @@ class SVGTOIMAGE{
|
||||
$lastY = 0;
|
||||
while ($i < $nbArray) {
|
||||
// Changement de départ
|
||||
if(substr($pathArray[$i], 0, 1) == 'M'){
|
||||
if(strtolower(substr($pathArray[$i], 0, 1)) == 'm'){
|
||||
$lastX = $this->_parseInt($pathArray[$i]);
|
||||
$lastY = $this->_parseInt($pathArray[$i+1]);
|
||||
$lastOpe = 'M';
|
||||
$lastOpe = 'm';
|
||||
$i=$i+2;
|
||||
|
||||
}elseif(substr($pathArray[$i], 0, 1) == 'L'){
|
||||
// Ligne
|
||||
}elseif(strtolower(substr($pathArray[$i], 0, 1)) == 'l' || (is_numeric($pathArray[$i]) && strtolower($lastOpe) == 'l')){
|
||||
$newX = $this->_parseInt($pathArray[$i]);
|
||||
$newY = $this->_parseInt($pathArray[$i+1]);
|
||||
$this->_drawLine($lastX , $lastY , $newX , $newY , IMG_COLOR_STYLED);
|
||||
$lastOpe = 'L';
|
||||
$lastOpe = 'l';
|
||||
$lastX = $newX;
|
||||
$lastY = $newY;
|
||||
$i=$i+2;
|
||||
|
||||
}elseif(substr($pathArray[$i], 0, 1) == 'H'){
|
||||
// Ligne horizontale
|
||||
}elseif(strtolower(substr($pathArray[$i], 0, 1)) == 'h' || (is_numeric($pathArray[$i]) && strtolower($lastOpe) == 'h')){
|
||||
$newX = $this->_parseInt($pathArray[$i]);
|
||||
$this->_drawLine($lastX , $lastY , $newX , $lastY , IMG_COLOR_STYLED);
|
||||
$lastOpe = 'H';
|
||||
$lastOpe = 'h';
|
||||
$lastX = $newX;
|
||||
$i++;
|
||||
|
||||
}elseif(substr($pathArray[$i], 0, 1) == 'V'){
|
||||
// Ligne verticale
|
||||
}elseif(strtolower(substr($pathArray[$i], 0, 1)) == 'v' || (is_numeric($pathArray[$i]) && strtolower($lastOpe) == 'v')){
|
||||
$newY = $this->_parseInt($pathArray[$i]);
|
||||
$this->_drawLine($lastX , $lastY , $lastX , $newY , IMG_COLOR_STYLED);
|
||||
$lastY = $newY;
|
||||
$lastOpe = 'V';
|
||||
$lastOpe = 'v';
|
||||
$i++;
|
||||
|
||||
}elseif(substr($pathArray[$i], 0, 1) == 'C'){
|
||||
|
||||
// Courbe
|
||||
}elseif(strtolower(substr($pathArray[$i], 0, 1)) == 'c' || (is_numeric($pathArray[$i]) && strtolower($lastOpe) == '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]);
|
||||
if($this->_debug) $this->_log->message('Drawing curve : '.$lastX.' - '.$lastY.' - '.$control1x.' - '.$control1y.' - '.$control2x.' - '.$control2y.' - '.$newX.' - '.$newY);
|
||||
|
||||
$this->_drawCurve($lastX, $lastY, $control1x, $control1y, $control2x, $control2y, $newX, $newY, IMG_COLOR_STYLED);
|
||||
|
||||
// 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;
|
||||
$lastOpe = 'c';
|
||||
$i=$i+6;
|
||||
}elseif(is_numeric(substr($pathArray[$i], 0, 1))){
|
||||
switch($lastOpe){
|
||||
case 'L':
|
||||
$newX = $this->_parseInt($pathArray[$i]);
|
||||
$newY = $this->_parseInt($pathArray[$i+1]);
|
||||
$this->_drawLine($lastX , $lastY , $newX , $newY , IMG_COLOR_STYLED);
|
||||
$lastX = $newX;
|
||||
$lastY = $newY;
|
||||
$i=$i+2;
|
||||
break;
|
||||
case 'H':
|
||||
$newX = $this->_parseInt($pathArray[$i]);
|
||||
$this->_drawLine($lastX , $lastY , $newX , $lastY , IMG_COLOR_STYLED);
|
||||
$lastX = $newX;
|
||||
$i++;
|
||||
break;
|
||||
case 'V':
|
||||
$newY = $this->_parseInt($pathArray[$i]);
|
||||
$this->_drawLine($lastX , $lastY , $lastX , $newY , IMG_COLOR_STYLED);
|
||||
$lastY = $newY;
|
||||
$i++;
|
||||
break;
|
||||
case 'Z':
|
||||
if($this->_debug) $this->_log->error('2 bouclages dans une boucle');
|
||||
$i++;
|
||||
break;
|
||||
default : //polyline
|
||||
if($this->_debug) $this->_log->error('last opé inconnue '.$lastOpe);
|
||||
$lastX = $this->_parseInt($pathArray[$i]);
|
||||
$lastY = $this->_parseInt($pathArray[$i+1]);
|
||||
$lastOpe = 'L';
|
||||
$i=$i+2;
|
||||
break;
|
||||
}
|
||||
|
||||
}elseif(substr($pathArray[$i], 0, 1) == 'Z'){
|
||||
// Dernière ligne droite
|
||||
}elseif(strtolower(substr($pathArray[$i], 0, 1)) == 'z' || (is_numeric(substr($pathArray[$i], 0, 1)) && strtolower($lastOpe) == 'z')){
|
||||
if($lastOpe == 'z' && $this->_debug) $this->_log->error('2 bouclages dans une boucle');
|
||||
$this->_drawLine($lastX , $lastY , $this->_parseInt($pathArray[0]) , $this->_parseInt($pathArray[1]) , IMG_COLOR_STYLED);
|
||||
$lastOpe = 'Z'; //utile?
|
||||
$lastOpe = 'z'; //utile?
|
||||
$i++;
|
||||
}else
|
||||
$i++; // au cas où pour éviter une boucle infinie.
|
||||
// Polyline
|
||||
}else{
|
||||
$lastX = $this->_parseInt($pathArray[$i+2]);
|
||||
$lastY = $this->_parseInt($pathArray[$i+3]);
|
||||
$lastOpe = 'l'; // s'il n'a aucune lettre, c'est une polyline, donc des... lignes.
|
||||
$i=$i+2;
|
||||
}
|
||||
if($this->_debug) $this->_log->message('counter :'.$i);
|
||||
}
|
||||
imagecolordeallocate( $this->_image, $colorStroke);
|
||||
@ -732,6 +747,7 @@ class SVGTOIMAGE{
|
||||
public function toImage($format = 'png', $path = null){
|
||||
$writeDesc = null;
|
||||
$this->_image = imagecreatetruecolor($this->_getImageWidth(), $this->_getImageHeight());
|
||||
imagefilledrectangle($this->_image, 0, 0 , $this->_getImageWidth(), $this->_getImageHeight(), $this->_allocateColor('white'));
|
||||
imagealphablending($this->_image, true);
|
||||
//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){
|
||||
|
Loading…
Reference in New Issue
Block a user