Laravel 控制器使用干预图像进行图像大小调整/裁剪输出像素化图像

问题描述 投票:0回答:1

我为 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;
    }
}
php laravel gd intervention
1个回答
0
投票

如果您在 Laravel 中使用 Intervention Image 调整大小/裁剪图像并且输出图像像素化,则可能是因为您没有正确设置图像质量。

调整图像大小或裁剪图像时,图像质量会受到影响。为保证输出图像的质量,保存图像时需要设置质量参数。这是一个例子:

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。

通过正确设置质量参数,您可以确保输出图像质量高且不像素化。您可以尝试不同的质量值来找到最适合您图像的设置。

© www.soinside.com 2019 - 2024. All rights reserved.