php Laravel控制器使用Intervention Image调整图像大小/裁剪输出像素化图像

rkue9o1l  于 2023-04-28  发布在  PHP
关注(0)|答案(1)|浏览(216)

我为Laravel创建了这个类,它利用Intervention Image Cache来处理和缓存用户上传的图像。这个类是通过GET端点调用的,该端点传递图像URI、目标宽度/高度和裁剪w/h(如果适用)等信息。
图像的大小和裁剪到正确的尺寸;然而,图像似乎略有像素化,就好像它们潜在地被调整到更小的尺寸,然后稍微吹回。我试图弄清楚我是否以错误的顺序进行调整大小/裁剪操作,以及是否这可能导致问题。无论是否传递了裁剪参数,它似乎都在发生。我也试过用JPG作为输出格式,但没有成功。有什么想法吗

<?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;
    }
}
xuo3flqw

xuo3flqw1#

如果您使用干预图像在Laravel中调整图像大小/裁剪图像,并且输出图像被像素化,这可能是因为您没有正确设置图像质量。
调整图像大小或裁剪图像时,图像质量可能会受到影响。为了保证输出图像的高质量,您需要在保存图像时设置质量参数。下面是一个例子:

use Intervention\Image\Facades\Image;

public function resizeImage()
{
    $image = Image::make(public_path('images/image.jpg'));
    $image->resize(200, null, function ($constraint) {
        $constraint->aspectRatio();
    });
    $image->save(public_path('images/resized-image.jpg'), 80);
}

在上面的例子中,我们在保存调整大小的图像时将质量参数设置为80。这确保了输出图像具有高质量并且没有像素化。
您还可以在裁剪图像时设置质量参数。下面是一个例子:

use Intervention\Image\Facades\Image;

public function cropImage()
{
    $image = Image::make(public_path('images/image.jpg'));
    $image->crop(200, 200, 100, 100);
    $image->save(public_path('images/cropped-image.jpg'), 80);
}

在本例中,我们在保存裁剪图像时将质量参数设置为80。
通过正确设置质量参数,您可以确保输出图像具有高质量且没有像素化。您可以尝试使用不同的质量值来找到图像的最佳设置。

相关问题