Laravel controller using Intervention Image for image resize/crop is outputting pixelated images - Hack The Tech - Latest News related to Computer and Technology

Hack The Tech - Latest News related to Computer and Technology

Get Daily Latest News related to Computer and Technology and hack the world.

Tuesday, April 25, 2023

Laravel controller using Intervention Image for image resize/crop is outputting pixelated images

I've made this class for Laravel that leverages Intervention Image Cache to process and cache images uploaded by the user. This class is called via a GET endpoint that passes things like image URI, target width/height, and crop w/h where applicable.

The images are resized and cropped to the right dimensions; however, the images seem to be slightly pixelated, as if they were potentially resized to a smaller dimension and then slightly blown back up. I'm trying to figure out if I'm doing resize/crop operations in the wrong order and if that may be causing the issue. It seems to be happening regardless of whether there are crop parameters passed or not. I've tried with JPG as the output format as well with no success. Any thoughts?

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Intervention\Image\Exception\NotReadableException;
use Intervention\Image\Facades\Image;

/**
 * Class ImageCacheController
 *
 * Handles resizing, cropping and caching of modified images.
 */
class ImageCacheController extends Controller
{
    /**
     * Handles the image caching process.
     */
    public function __invoke(Request $request, $width, $height, $crop_x, $crop_y, string $uri): mixed
    {
        // Set dimensions to null if they are 'null' string, and cast them to integers
        $width = $this->convertNullString($width);
        $height = $this->convertNullString($height);
        $crop_x = $this->convertNullString($crop_x);
        $crop_y = $this->convertNullString($crop_y);

        // Get the image source
        $src = storage_path('app') . '/public/uploads/' . $uri;
        if (!file_exists($src)) {
            // If the image doesn't exist, return a 404
            return response('', 404);
        }

        try {

            $cachedImage = Image::cache(function ($image) use ($src, $width, $height, $crop_x, $crop_y, $uri) {
                $rawImage = Image::make($src);
                $originalWidth = $rawImage->getWidth();
                $originalHeight = $rawImage->getHeight();

                // Calculate the ratio of the original image
                $ratio = $originalWidth / $originalHeight;

                // If the height is null, set it to 0
                $cropHeight = $height === null ? 0 : $height;
                $cropWidth = $width;

                // If the cropHeight is less than 1, set it to the width divided by the ratio
                if ($cropHeight < 1) {
                    $cropHeight = (int)floor($width / $ratio);
                    $height = null;
                }

                $image = $image->make($src);

                $image = $image->resize($cropWidth === null ? null : $width, $height, function ($constraint) {
                    $constraint->aspectRatio();
                });

                // If the crop_x and crop_y are set, crop the image
                if (isset($crop_x, $crop_y) && $cropHeight !== null) {
                    $image = $image->fit($width, $cropHeight)->trim();
                }

                // Encode the image to webp
                return $image->encode('webp', 95);
            }, 7776000, true);

            return $cachedImage->response();

        } catch (NotReadableException $e) {
            // If there was an error reading the image, return a 404
            return response($e->getMessage(), 404);
        }
    }

    /**
     * Converts the string 'null' to a real null value.
     *
     * @param mixed $value
     * @return mixed|null
     */
    private function convertNullString(mixed $value): ?int
    {
        return $value === 'null' ? null : (int)$value;
    }
}


source https://stackoverflow.com/questions/76094878/laravel-controller-using-intervention-image-for-image-resize-crop-is-outputting

No comments:

Post a Comment