03 - Le Cœur du Système : ImageProcessingService
J’ai centralisé toute l’intelligence du traitement dans un service unique pour garantir la réutilisabilité et la propreté de votre code.
Le Code Source Complet
Voici l’implémentation exacte de app/Services/ImageProcessingService.php :
<?php
declare(strict_types=1);
namespace App\Services;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Laravel\Facades\Image;
use Intervention\Image\Typography\FontFactory;
class ImageProcessingService
{
public function processBlogCover(string $path): void
{
$fullPath = storage_path('app/public/' . $path);
if (! file_exists($fullPath)) {
return;
}
// 1. Chargement (v4 API)
$image = Image::decode($fullPath);
// 2. Filigrane répétitif
$this->addRepeatingWatermark($image, 'www.devinsto.com');
// 3. Logo Branding
$this->addLogo($image);
// 4. Sauvegarde optimisée (80% qualité)
$image->save($fullPath, quality: 80);
}
private function addRepeatingWatermark(ImageInterface $image, string $text): void
{
$width = $image->width();
$height = $image->height();
// J'ai créé un motif de 300x200px pour une répétition harmonieuse
$tileWidth = 300;
$tileHeight = 200;
$tile = Image::createImage($tileWidth, $tileHeight);
$fontPath = base_path('resources/font/Nunito-Regular.ttf');
$tile->text($text, (int) ($tileWidth / 2), (int) ($tileHeight / 2), function (FontFactory $font) use ($fontPath) {
if (file_exists($fontPath)) {
$font->file($fontPath);
}
$font->size(20);
$font->color('ffffff44'); // Blanc avec 44% d'opacité
$font->align('center', 'center'); // Correction API v3/v4 : pas de valign()
$font->angle(45);
});
// J'insère le motif en boucle sur toute l'image
for ($x = 0; $x < $width; $x += $tileWidth) {
for ($y = 0; $y < $height; $y += $tileHeight) {
$image->insert($tile, $x, $y, 'top-left');
}
}
}
private function addLogo(ImageInterface $image): void
{
$logoPath = public_path('android-chrome-512x512.png');
if (file_exists($logoPath)) {
$logo = Image::decode($logoPath);
// Redimensionnement dynamique à 8% de la largeur
$logoWidth = (int) ($image->width() * 0.08);
$logo->scale(width: $logoWidth);
// Insertion au centre à droite avec marge de 40px
$image->insert($logo, 40, 0, 'right');
}
}
}
Décryptage de mes choix techniques
1. La gestion de la police (Nunito)
J’ai choisi de pointer vers resources/font/Nunito-Regular.ttf. J’ai ajouté une vérification file_exists pour éviter que le script ne plante si la police est absente (dans ce cas, Intervention utilise la police système par défaut).
2. Le calcul du Logo
J’ai utilisé $logo->scale(width: $logoWidth). Pourquoi ? Contrairement à resize(), scale() conserve l’aspect ratio automatiquement sans que j’aie besoin de spécifier la hauteur. C’est plus sûr pour votre logo.
3. L’alignement du texte
J’ai utilisé $font->align('center', 'center'). C’est une spécificité de la nouvelle API Intervention Image. L’ancien valign() n’existe plus, tout se passe maintenant dans la méthode align().
Prêt à passer à la suite ?
Vous avez terminé cette leçon sur 03 - Le Cœur du Système : ImageProcessingService. Continuez votre apprentissage avec la prochaine leçon ou explorez d'autres formations.