Skip to content

Commit

Permalink
Preserve the original image quality if known
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonkelly committed Jan 2, 2025
1 parent 37b895b commit c706fb9
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- Database rows with foreign keys referencing nonexistent rows are now deleted via garbage collection.
- Pages which contain image transform generation URLs now set no-cache headers. ([#16195](https://github.com/craftcms/cms/discussions/16195))
- Action requests (such as `actions/app/health-check`) now send no-cache headers by default. ([#16364](https://github.com/craftcms/cms/pull/16364))
- Image cleansing now preserves the original image quality, if known.
- Fixed a bug where `craft\config\GeneralConfig::safeMode()` set Safe Mode to `false` by default.
- Fixed a bug where Craft wasn’t auto-rotating or flipping images uploaded with a mirrored EXIF orientation.
- Updated Twig to 3.15. ([#16207](https://github.com/craftcms/cms/discussions/16207))
33 changes: 21 additions & 12 deletions src/image/Raster.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use craft\helpers\FileHelper;
use craft\helpers\Image as ImageHelper;
use Imagick;
use ImagickException;
use Imagine\Exception\NotSupportedException;
use Imagine\Exception\RuntimeException;
use Imagine\Gd\Imagine as GdImagine;
Expand All @@ -29,7 +30,6 @@
use Imagine\Image\Point;
use Imagine\Imagick\Imagine as ImagickImagine;
use Throwable;
use yii\base\ErrorException;

/**
* Raster class is used for raster image manipulations.
Expand Down Expand Up @@ -559,27 +559,36 @@ public function saveAs(string $targetPath, bool $autoQuality = false): bool
{
$extension = mb_strtolower(pathinfo($targetPath, PATHINFO_EXTENSION));

$options = $this->_getSaveOptions(null, $extension);
$targetPath = pathinfo($targetPath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . pathinfo($targetPath, PATHINFO_FILENAME) . '.' . pathinfo($targetPath, PATHINFO_EXTENSION);
$quality = null;

try {
if ($autoQuality && in_array($extension, ['jpeg', 'jpg', 'png'], true)) {
clearstatcache();
App::maxPowerCaptain();

$originalSize = filesize($this->_imageSourcePath);
$tempFile = $this->_autoGuessImageQuality($targetPath, $originalSize, $extension, 0, 200);
try {
rename($tempFile, $targetPath);
} catch (ErrorException $e) {
Craft::warning("Unable to rename \"$tempFile\" to \"$targetPath\": " . $e->getMessage(), __METHOD__);
if (Craft::$app->getImages()->getIsImagick() && method_exists(Imagick::class, 'getImageCompressionQuality')) {
try {
$image = new Imagick($this->_imageSourcePath);
$quality = $image->getImageCompressionQuality();
} catch (ImagickException) {
}
}
} else {
if (Craft::$app->getImages()->getIsImagick()) {
ImageHelper::cleanExifDataFromImagickImage($this->_image->getImagick());

if ($quality === null) {
$originalSize = filesize($this->_imageSourcePath);
$tempFile = $this->_autoGuessImageQuality($targetPath, $originalSize, $extension, 0, 200);
rename($tempFile, $targetPath);
return true;
}
$this->_image->save($targetPath, $options);
}

if (Craft::$app->getImages()->getIsImagick()) {
ImageHelper::cleanExifDataFromImagickImage($this->_image->getImagick());
}

$options = $this->_getSaveOptions($quality, $extension);
$this->_image->save($targetPath, $options);
} catch (RuntimeException $e) {
throw new ImageException(Craft::t('app', 'Failed to save the image.'), $e->getCode(), $e);
}
Expand Down

0 comments on commit c706fb9

Please sign in to comment.