Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Retain file type but ensure 'progressive' image
Realized after having a think about my previous commits that the intent
of the original function was also to ensure images are stored in a
progressively loading format. With these further changes, I think the
original intern is captured more closely.

Signed-off-by: JelleV <[email protected]>
  • Loading branch information
jcjveraa committed Jun 9, 2022
commit 8b7afdb23df76ab373342eaeb37d15c7b80417bb
54 changes: 37 additions & 17 deletions apps/theming/lib/ImageManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,28 +232,29 @@ public function updateImage(string $key, string $tmpFile): string {
}

if ($key === 'background' && strpos($detectedMimeType, 'image/svg') === false && strpos($detectedMimeType, 'image/gif') === false) {
$tmpFile = $this->getResizedImagePathIfResizeIsSmaller($tmpFile);
$tmpFile = $this->getResizedFilePath($tmpFile, $detectedMimeType);
}

$target->putContent(file_get_contents($tmpFile));
return $detectedMimeType;
}

/**
* Returns the file path of the file stored as a png and resized to be
* a maximum of 4096 pixels wide (preserving aspect ratio), but only if the resizing
* results in an image that has a smaller file size than the uploaded file.
* For png and webp files: Returns the file path of the file resized to a maximum of 4096 pixels wide (preserving aspect ratio)
* but only if the resizing results in an image that has a smaller file size than the uploaded file. For jpeg files:
* Will always re-save the file at quality 80 (not too low, not too high to create large files).
*
* @param string $originalTmpFile The tmpFile(path) as uploaded by the user
* @return string Location of the resized file, or the original
* @param string $detectedMimeType The the MIME type of the file as uploaded by the user
* @return string Location of the resized file, or the original if that was the smaller of the two
*/
private function getResizedImagePathIfResizeIsSmaller(string $originalTmpFile): string
private function getResizedFilePath(string $originalTmpFile, string $detectedMimeType): string
{
// Optimize the image since some people may upload images that will be
// either to big or are not progressive rendering.
// Optimize the image since some people may upload images that will be
// either to big or are not progressive rendering.
$newImage = @imagecreatefromstring(file_get_contents($originalTmpFile));

// Preserve transparency
// Preserve transparency
imagesavealpha($newImage, true);
imagealphablending($newImage, true);

Expand All @@ -263,16 +264,35 @@ private function getResizedImagePathIfResizeIsSmaller(string $originalTmpFile):
$outputImage = imagescale($newImage, $newWidth, $newHeight);

imageinterlace($outputImage, 1);
imagepng($outputImage, $newImageTmpFile, 8);
imagedestroy($outputImage);

// only actually use the image if it is an improvement
$newImageIsSmaller = filesize($newImageTmpFile) <= filesize($originalTmpFile);
if ($newImageIsSmaller) {
return $newImageTmpFile;
} else {
return $originalTmpFile;
$checkIfFileSizeWasReduced = false;

// Preserve the original file format
switch($detectedMimeType) {
case 'image/png':
imagepng($outputImage, $newImageTmpFile, 8);
$checkIfFileSizeWasReduced = true;
break;
case 'image/webp':
imagewebp($outputImage, $newImageTmpFile, 80);
$checkIfFileSizeWasReduced = true;
break;
case 'image/jpeg':
imagejpeg($outputImage, $newImageTmpFile, 80);
// we have no convenient way if knowing if the original file was a progressive
// jpeg, so we just need to re-save it.
$checkIfFileSizeWasReduced = false;
break;
}

imagedestroy($outputImage);

$newImageIsLarger = filesize($newImageTmpFile) >= filesize($originalTmpFile);
if($checkIfFileSizeWasReduced && $newImageIsLarger) {
return $originalTmpFile;
}

return $newImageTmpFile;
}

/**
Expand Down