[Cropperjs] Add image rotation in php side

This commit is contained in:
MrYamous
2026-03-19 09:39:57 +01:00
committed by Hugo Alliaume
parent 59240d00c6
commit 09fa3ebb68
4 changed files with 145 additions and 2 deletions

View File

@@ -1,5 +1,9 @@
# CHANGELOG
## 2.34
- Deprecate calling `Crop::getCroppedImage()` and `Crop::getCroppedThumbnail()` without explicitly passing `true` for the $applyRotation parameter. It will always be `true` in 3.0
## 2.30
- Ensure compatibility with PHP 8.5

View File

@@ -32,6 +32,7 @@
"intervention/image": "^2.5",
"symfony/config": "^5.4|^6.0|^7.0|^8.0",
"symfony/dependency-injection": "^5.4|^6.0|^7.0|^8.0",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/form": "^5.4|^6.0|^7.0|^8.0",
"symfony/http-kernel": "^5.4|^6.0|^7.0|^8.0",
"symfony/options-resolver": "^5.4|^6.0|^7.0|^8.0",

View File

@@ -46,6 +46,7 @@ class Crop
'y' => 0,
'width' => null,
'height' => null,
'rotate' => 0,
];
public function __construct(ImageManager $imageManager, string $filename)
@@ -54,8 +55,11 @@ class Crop
$this->filename = $filename;
}
public function getCroppedThumbnail(int $maxWidth, int $maxHeight, string $format = 'jpg', int $quality = 80): string
public function getCroppedThumbnail(int $maxWidth, int $maxHeight, string $format = 'jpg', int $quality = 80, bool $applyRotation = false): string
{
if (\func_num_args() < 5 || false === $applyRotation) {
trigger_deprecation('symfony/ux-cropperjs', '2.34', 'Not passing "true" to the "$applyRotation" argument of "%s()" is deprecated. Rotation will be applied by default in Symfony UX 3.0.', __METHOD__);
}
$image = $this->createCroppedImage();
$image->resize($maxWidth, $maxHeight, static function ($constraint) {
@@ -63,13 +67,20 @@ class Crop
$constraint->upsize();
});
if ($applyRotation && !empty($this->options['rotate'])) {
$image->rotate(-1 * $this->options['rotate']);
}
$image->encode($format, $quality);
return $image->getEncoded();
}
public function getCroppedImage(string $format = 'jpg', int $quality = 80): string
public function getCroppedImage(string $format = 'jpg', int $quality = 80, bool $applyRotation = false): string
{
if (\func_num_args() < 3 || false === $applyRotation) {
trigger_deprecation('symfony/ux-cropperjs', '2.34', 'Not passing "true" to the "$applyRotation" argument of "%s()" is deprecated. Rotation will be applied by default in Symfony UX 3.0.', __METHOD__);
}
$image = $this->createCroppedImage();
// Max size
@@ -80,6 +91,10 @@ class Crop
});
}
if ($applyRotation && !empty($this->options['rotate'])) {
$image->rotate(-1 * $this->options['rotate']);
}
$image->encode($format, $quality);
return $image->getEncoded();

123
tests/Model/CropTest.php Normal file
View File

@@ -0,0 +1,123 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\UX\Cropperjs\Tests\Model;
use Intervention\Image\ImageManager;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\UX\Cropperjs\Model\Crop;
/**
* @internal
*/
class CropTest extends TestCase
{
use ExpectDeprecationTrait;
private string $testImagePath;
protected function setUp(): void
{
$this->testImagePath = tempnam(sys_get_temp_dir(), 'crop_test_').'.jpg';
ob_start();
imagejpeg(imagecreatetruecolor(200, 100), $this->testImagePath);
ob_end_clean();
}
protected function tearDown(): void
{
if (file_exists($this->testImagePath)) {
unlink($this->testImagePath);
}
}
private function createCrop(int $rotate = 0): Crop
{
$imageManager = new ImageManager();
$crop = new Crop($imageManager, $this->testImagePath);
$crop->setOptions(json_encode([
'width' => null,
'height' => null,
'rotate' => $rotate,
]));
return $crop;
}
public function testGetCroppedImageWithRotation()
{
$crop = $this->createCrop(rotate: 90);
$result = $crop->getCroppedImage(applyRotation: true);
$image = imagecreatefromstring($result);
$this->assertSame(100, imagesx($image));
$this->assertSame(200, imagesy($image));
}
public function testGetCroppedImageWithoutRotation()
{
$crop = $this->createCrop(rotate: 0);
$result = $crop->getCroppedImage(applyRotation: true);
$image = imagecreatefromstring($result);
$this->assertSame(200, imagesx($image));
$this->assertSame(100, imagesy($image));
}
/**
* @group legacy
*/
public function testGetCroppedImageWithApplyRotationFalseTriggersDeprecation()
{
$crop = $this->createCrop();
$this->expectDeprecation('Since symfony/ux-cropperjs 2.34: Not passing "true" to the "$applyRotation" argument of "Symfony\UX\Cropperjs\Model\Crop::getCroppedImage()" is deprecated. Rotation will be applied by default in Symfony UX 3.0.');
$crop->getCroppedImage(applyRotation: false);
}
public function testGetCroppedThumbnailWithRotation()
{
$crop = $this->createCrop(rotate: 90);
$result = $crop->getCroppedThumbnail(200, 200, applyRotation: true);
$image = imagecreatefromstring($result);
$this->assertSame(100, imagesx($image));
$this->assertSame(200, imagesy($image));
}
public function testGetCroppedThumbnailWithoutRotation()
{
$crop = $this->createCrop(rotate: 0);
$result = $crop->getCroppedThumbnail(200, 200, applyRotation: true);
$image = imagecreatefromstring($result);
$this->assertSame(200, imagesx($image));
$this->assertSame(100, imagesy($image));
}
/**
* @group legacy
*/
public function testGetCroppedThumbnailWithApplyRotationFalseTriggersDeprecation()
{
$crop = $this->createCrop();
$this->expectDeprecation('Since symfony/ux-cropperjs 2.34: Not passing "true" to the "$applyRotation" argument of "Symfony\UX\Cropperjs\Model\Crop::getCroppedThumbnail()" is deprecated. Rotation will be applied by default in Symfony UX 3.0.');
$crop->getCroppedThumbnail(200, 200, applyRotation: false);
}
}