Effet triangle dans une image

Superposez des triangles sur une image en GD

Cet article est la suite des deux articles sur le pixel art et animer un pixel art.

L’objectif est de placer des triangles sur une image histoire de lui donner un effet un peu cool.

Je vais reprendre la même base de code que pour les articles précédents et j’y additionne une nouvelle shape. J’adapte bien sûr les paramètres.

//params for class
$params = array(
	"fileName"            => "snow.jpg",
	"nbrPoint"            => 10,
	"shape"               => "triangle",
	"rangeSizeShape"	  => array(0,100),
	"minOpacity"		  => 30,	//0 = hide | 100 = visible
	"lowerizationLvl"	  => 1,
	"borderLess"		  => false,
	"exportMode"		  => "image",				
);

//launch object	
$imageRendering = new pixelArt($params);
$imageRendering->collectPixel();
$imageRendering->makingShape();

Je vais ajouter une nouvelle méthode, la méthode generatePoly (pour polygone), qui va me servir lors de la création de mon triangle. Elle prend en paramètre le point (coordonnées x et y). Dans cette méthode, je génère une taille ainsi qu’une direction aléatoire, le topOrBottom. Si la shape est un triangle, alors je construis les points x, y et z selon la taille et je retourne les points. Je définis anglePoly pour obtenir le nombre de coins, ça pourrait être fait en divisant le nombre points dans le tableau de retour mais je préfère cette manière.

public function generatePoly($point){
	
	//size of poly
	$size = rand($this->params["rangeSizeShape"][0], $this->params["rangeSizeShape"][1]);
	//direction of poly
	$topOrBottom = rand(0,1);			
	
	if( $this->params["shape"] == "triangle" ){
		//coordinate of point
		$pointX = $point["x"] - $size;
		$pointY = $point["x"] + $size;

		if( $topOrBottom == 0 ){
			$pointZ = $point["y"] - $size;
		}else{
			$pointZ = $point["y"] + $size;
		}
		
		//define number of point for GD function
		$this->anglePoly = 3;
		
		return array(
			$pointX, $point["y"], //x y
			$pointY, $point["y"], //x y
			$point["x"], $pointZ, //x y
		);
	}
	
}

Je copie-colle la méthode rect et je la renomme en triangle. Je lance alors la boucle sur tous les points collectés. Ensuite, j’exécute la méthode generatePoly e je lance la function GD imagefilledpolygon qui permet de dessiner un polygone avec les points. Enfin, je laisse la méthode finir le boulot comme pour rect.

public function triangle(){
	
	//check if point exist
	if( empty($this->listOfPoint) ){
		die("Empty listOfPoint");
	}
	
	//check if range for size of shape
	if( !isset($this->params["rangeSizeShape"][0]) || !isset($this->params["rangeSizeShape"][1]) ){
		die("Missing range size shape");	
	}
	
	//generate blank image 
	$tmpImage = $this->generateFusionImage();
	
	foreach($this->listOfPoint as $point){

		//posPoly 
		$posPoly = $this->generatePoly($point);
		
		//get size
		$sizeShape = $posPoly[1] - end($posPoly);

		//generate random opacity
		$opacity = $this->getOpacity($point["color"]["alpha"], $sizeShape);

		//prepare color
		$tmpColor = imagecolorallocatealpha($tmpImage, $point["color"]["red"], $point["color"]["green"], $point["color"]["blue"], $opacity);
		
		//create poly
		imagefilledpolygon( $tmpImage, $posPoly, $this->anglePoly, $tmpColor);

	}
	
	return $tmpImage;
		
}

L’image rendue avec quelques points n’est pas exceptionnelle. C’est logique car mon but est de fusionner l’image de départ avec les formes générées pour donner vraiment un effet un peu futuriste.

Fusion

Du coup, je modifie simplement la fonction qui retourne une image vierge par l’image d’origine, histoire que les triangles se placent directement sur celle-ci.

public function generateFusionImage($blank = true){
	if( $blank === true){	
		$tmpImage  	= imagecreatetruecolor($this->imageWidth, $this->imageHeight);
		$whiteBg 	= imagecolorallocate($tmpImage, 255, 255, 255);
		imagefill($tmpImage, 0, 0, $whiteBg);
		
		return $tmpImage;
	}else{
		return $this->imageRessource;
	}
}

Voici le rendu en superposant l’image et les formes.

Random Color

L’effet n’est pas exceptionnel sur ce genre d’image, car elle est assez pauvre en couleurs et donc la collecte de pixels va essentiellement se faire sur du blanc ou gris. C’est pourquoi j’ai décidé d’intégrer un système de génération aléatoire de couleurs.

Au niveau du constructeur, je détecte si le paramètre est défini.

//random color
if( isset($this->params["randomColor"]) && $this->imageRessource){
	$this->randomColor = true;
}

Ensuite, dans la méthode de collecte de pixels, juste avant de retourner le pixel, je définis randomColor à true et une couleur est générée aléatoirement.

if( $this->randomColor ){
	$tmpPixel["red"] = rand(0, 255);
	$tmpPixel["green"] = rand(0, 255);
	$tmpPixel["blue"] = rand(0, 255);
}

Et là, le rendu est beaucoup plus intéressant!

24/10/2017

Yann Vangampelaere - nouslesdevs -

Sinon jete un coup d’oeil aux autres catégories

Ma boîte aux lettres

Tu veux me demander quelque chose ?