Pas 23: Redimensionarea imaginilor
Redimensionarea imaginilor¶
Pe pagina de conferință, fotografiile sunt limitate la o dimensiune maximă de 200 x 150 pixeli. Cum rămâne cu optimizarea imaginilor și reducerea dimensiunii acestora dacă originalul încărcat este mai mare decât limitele?
Aceasta este o sarcină perfectă care poate fi adăugată la fluxul de lucru al comentariilor, probabil imediat după validarea comentariului și chiar înainte de publicarea acestuia.
Să adăugăm o nouă stare ready
și o tranziție optimize
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | --- a/config/packages/workflow.yaml
+++ b/config/packages/workflow.yaml
@@ -16,6 +16,7 @@ framework:
- potential_spam
- spam
- rejected
+ - ready
- published
transitions:
accept:
@@ -29,13 +30,16 @@ framework:
to: spam
publish:
from: potential_spam
- to: published
+ to: ready
reject:
from: potential_spam
to: rejected
publish_ham:
from: ham
- to: published
+ to: ready
reject_ham:
from: ham
to: rejected
+ optimize:
+ from: ready
+ to: published
|
Generează o reprezentare vizuală a noii configurații a fluxului de lucru pentru a valida faptul că descrie ceea ce dorim:
1 | $ symfony console workflow:dump comment | dot -Tpng -o workflow.png
|

Optimizarea imaginilor cu Imagine¶
Optimizarea imaginilor se va face grație lui GD (verifică dacă instalația PHP locală are extensia GD activată) și Imagine:
1 | $ symfony composer req "imagine/imagine:^1.2"
|
Redimensionarea unei imagini se poate face prin următoarea clasă de servicii:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | namespace App;
use Imagine\Gd\Imagine;
use Imagine\Image\Box;
class ImageOptimizer
{
private const MAX_WIDTH = 200;
private const MAX_HEIGHT = 150;
private $imagine;
public function __construct()
{
$this->imagine = new Imagine();
}
public function resize(string $filename): void
{
list($iwidth, $iheight) = getimagesize($filename);
$ratio = $iwidth / $iheight;
$width = self::MAX_WIDTH;
$height = self::MAX_HEIGHT;
if ($width / $height > $ratio) {
$width = $height * $ratio;
} else {
$height = $width / $ratio;
}
$photo = $this->imagine->open($filename);
$photo->resize(new Box($width, $height))->save($filename);
}
}
|
După optimizarea fotografiei, stocăm noul fișier în locul celui original. Însă s-ar putea să dorești să păstrezi imaginea originală.
Adăugarea unui nou pas în fluxul de lucru¶
Modifică fluxul de lucru pentru a gestiona noua stare:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | --- a/src/MessageHandler/CommentMessageHandler.php
+++ b/src/MessageHandler/CommentMessageHandler.php
@@ -2,6 +2,7 @@
namespace App\MessageHandler;
+use App\ImageOptimizer;
use App\Message\CommentMessage;
use App\Repository\CommentRepository;
use App\SpamChecker;
@@ -21,10 +22,12 @@ class CommentMessageHandler implements MessageHandlerInterface
private $bus;
private $workflow;
private $mailer;
+ private $imageOptimizer;
private $adminEmail;
+ private $photoDir;
private $logger;
- public function __construct(EntityManagerInterface $entityManager, SpamChecker $spamChecker, CommentRepository $commentRepository, MessageBusInterface $bus, WorkflowInterface $commentStateMachine, MailerInterface $mailer, string $adminEmail, LoggerInterface $logger = null)
+ public function __construct(EntityManagerInterface $entityManager, SpamChecker $spamChecker, CommentRepository $commentRepository, MessageBusInterface $bus, WorkflowInterface $commentStateMachine, MailerInterface $mailer, ImageOptimizer $imageOptimizer, string $adminEmail, string $photoDir, LoggerInterface $logger = null)
{
$this->entityManager = $entityManager;
$this->spamChecker = $spamChecker;
@@ -32,7 +35,9 @@ class CommentMessageHandler implements MessageHandlerInterface
$this->bus = $bus;
$this->workflow = $commentStateMachine;
$this->mailer = $mailer;
+ $this->imageOptimizer = $imageOptimizer;
$this->adminEmail = $adminEmail;
+ $this->photoDir = $photoDir;
$this->logger = $logger;
}
@@ -64,6 +69,12 @@ class CommentMessageHandler implements MessageHandlerInterface
->to($this->adminEmail)
->context(['comment' => $comment])
);
+ } elseif ($this->workflow->can($comment, 'optimize')) {
+ if ($comment->getPhotoFilename()) {
+ $this->imageOptimizer->resize($this->photoDir.'/'.$comment->getPhotoFilename());
+ }
+ $this->workflow->apply($comment, 'optimize');
+ $this->entityManager->flush();
} elseif ($this->logger) {
$this->logger->debug('Dropping comment message', ['comment' => $comment->getId(), 'state' => $comment->getState()]);
}
|
Reține că $photoDir
este injectat automat deoarece am definit un container bind pe această denumire a variabilei într-un pas anterior:
1 2 3 4 | services:
_defaults:
bind:
$photoDir: "%kernel.project_dir%/public/uploads/photos"
|
Stocarea datelor încărcate în producție¶
Am definit deja în .symfony.cloud.yaml
un director special cu drepturi de scriere și de citire pentru fișierele încărcate. Dar montarea directorului este locală. Dacă dorim ca atât consumatorul de mesaje, cât și containerul web să poată accesa acel director, trebuie să creăm un serviciu destinat fișierelor:
1 2 3 4 5 6 7 8 9 10 | --- a/.symfony/services.yaml
+++ b/.symfony/services.yaml
@@ -19,3 +19,7 @@ varnish:
vcl: !include
type: string
path: config.vcl
+
+files:
+ type: network-storage:1.0
+ disk: 256
|
Folosiți-l pentru directorul de încărcare a fotografiilor:
1 2 3 4 5 6 7 8 9 10 11 | --- a/.symfony.cloud.yaml
+++ b/.symfony.cloud.yaml
@@ -41,7 +41,7 @@ web:
mounts:
"/var": { source: local, source_path: var }
- "/public/uploads": { source: local, source_path: uploads }
+ "/public/uploads": { source: service, service: files, source_path: uploads }
hooks:
build: |
|
Acest lucru ar trebui să fie suficient pentru ca noile implementări să funcționeze în producție.
- « Previous Pas 22: Stilarea interfeței cu Webpack
- Next » Pas 24: Rulând sarcinile Cron
This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.