首页 > 解决方案 > PHP 更新:使用 Imagick 进行图像处理不起作用

问题描述

在 PHP5.3 上使用的 Imagick 在图像的四个角上进行四舍五入的功能不适用于 PHP7.3。
如果在PHP7.3中做这些事情,原图会消失,输出透明背景。
php错误日志没有任何输出,所以它似乎不是语法错误,但我遇到了麻烦,因为没有调试任何东西。
你有什么主意吗?
抱歉,代码太长了。
删除了一些重复的代码,例如创建参数。php

define('DEFAULT_RADIUS', 10);
... 

if (isset($_GET['i'])) {
    $params = getParams();

    try {
        $img = new Imagick();
        $img->readImage($params['file']);
        $width  = isset($_GET['w']) ? (int)$_GET['w'] : $img->getImageWidth();
        $height = isset($_GET['h']) ? (int)$_GET['h'] : $img->getImageHeight();
        preg_match('/JPE?G|GIF|PNG/i', $params['format'])
            ? $img->setImageFormat($params['format'])
            : $params['format'] = $img->getImageFormat();

        if (   $width  !== $img->getImageWidth()
            || $height !== $img->getImageHeight()) {
            $img->scaleImage($width, $height, $params['isFit']);
            if ($params['isFit']) {
                $width  = $img->getImageWidth();
                $height = $img->getImageHeight();
            }
        }

        // Image crop
        if ($params['clip'] && 4 <= count($params['clip'])) {
            cropImage($img, $params['clip'], $params['origin']);
        }

        // Creating an image
        if (isset($_GET['_on_'])) {
            coverImage($img);
        }

        // Rounded corners
        roundCornersImage($img, $params['radius'],
                          $params['borderWidth'], $params['borderColor']);

        if (!$params['transparent']
            || ($params['format'] !== 'GIF' && $params['format'] !== 'PNG')
        ) {
            setBackgroundColor($img, $params['bgcolor']);
        }
        if ($params['quality'] !== -1) {
            $quality = 100 < $params['quality'] ? 100 : $params['quality'];
            $img->setCompressionQuality($quality);
        }
        header('Content-type: image/' . $params['format']);
        print $img;

        $img->destroy();
    }
    catch (ImagickException $e) {}
}
function cropImage(&$img, $rect, $origin)
{
    $rect = changeRectFromOrigin($rect, $origin,
                                 $img->getImageWidth(),
                                 $img->getImageHeight());
    $img->cropImage((int)$rect[2], (int)$rect[3],
                    (int)$rect[0], (int)$rect[1]);
}

function encodeFileName($matches)
{
    if (isset($matches[1]) && isset($matches[2])) {
        if (preg_match('/^https?:\/\//', $matches[1])) {
            $path = explode('/', $matches[2]);
            $length = count($path);
            for ($i = 0; $i < $length; $i++) {
                $path[$i] = rawurlencode($path[$i]);
            }
            return $matches[1] . implode('/', $path);
        }
        else if (preg_match('/^\//', $matches[1])) {
             $matches[1] = $_SERVER['DOCUMENT_ROOT'] . '/';
             return $matches[1] . $matches[2];
        }
    }
    return $matches[0];
}

function getParams()
{
    $i = '';
    if (isset($_GET['i'])) {
        $pattern = '/(https?:\/\/.*?\/|\.?\/)(.*?)$/';
        $i = preg_replace_callback($pattern, 'encodeFileName', $_GET['i']);
    }
    return array(
        'file'        => $i,
        'radius'      => isset($_GET['r']) ? $_GET['r'] : DEFAULT_RADIUS,
    );
}


function checkOriginValue($origin)
{
    $origin = strtoupper($origin);
    switch ($origin) {
        case CLIP_ORIGIN_TOP_LEFT:
        case CLIP_ORIGIN_TOP:
            break;

        default:
            $origin = CLIP_ORIGIN_TOP_LEFT;
    }
    return $origin;
}

function changeRectFromOrigin($rect, $origin, $width, $height)
{
    if (4 <= count($rect)) {
        $origin = checkOriginValue($origin);
        if (   $origin === CLIP_ORIGIN_BOTTOM
            || $origin === CLIP_ORIGIN_BOTTOM_LEFT
            || $origin === CLIP_ORIGIN_BOTTOM_RIGHT) {
            $rect[1] = $height - (int)$rect[1] - (int)$rect[3];
        }
    }
    return $rect;
}

function roundCornersImage(&$img,
        $radius      = DEFAULT_RADIUS,
        $borderWidth = DEFAULT_BORDER_WIDTH,
        $borderColor = DEFAULT_BORDER_COLOR
) {
    $width  = $img->getImageWidth();
    $height = $img->getImageHeight();
    $radius = (int)$radius;

    $draw = new ImagickDraw();
    $draw->setFillColor(new ImagickPixel('#FFFFFF'));
    $draw->setStrokeWidth(0);
    $draw->roundRectangle(0, 0, $width - 1, $height - 1, $radius, $radius);

    $mask = new Imagick();
    $mask->newImage($width, $height, 'none');
    $mask->drawImage($draw);
    $mask->setImageFormat($img->getImageFormat());
    $mask->compositeImage($img, Imagick::COMPOSITE_IN,
                          0, 0, Imagick::CHANNEL_ALL);
    $img = $mask;

    if (0 < $borderWidth) {
        $borderColor = preg_match('/([0-9a-f]{2}){3}/i', $borderColor)
            ? '#' . $borderColor : new ImagickPixel($borderColor);

        $pos  = (int)($borderWidth / 2);
        $even = (int)($borderWidth % 2 === 0);
        $borderRadius = $radius - $borderWidth / 2;

        $draw = new ImagickDraw();
        $draw->setStrokeAntialias(true);
        $draw->setFillColor(new ImagickPixel('#FFFFFF'));
        $draw->setFillOpacity(0);
        $draw->setStrokeColor($borderColor);
        $draw->setStrokeWidth($borderWidth);
        $draw->roundRectangle($pos, $pos,
                              $width  - $borderWidth + $pos - $even,
                              $height - $borderWidth + $pos - $even,
                              $borderRadius, $borderRadius);

        $img->drawImage($draw);
    }

    $draw->clear();
    $draw->destroy();
}

function setBackgroundColor(&$img, $color)
{
    $bg = new Imagick();
    $bgcolor = preg_match('/([0-9a-f]{2}){3}/i', $color)
            ? '#' . $color : new ImagickPixel($color);
    $bg->newImage($img->getImageWidth(), $img->getImageHeight(), $bgcolor);
    $bg->setImageFormat($img->getImageFormat());
    $bg->compositeImage($img, Imagick::COMPOSITE_DEFAULT,
                        0, 0, Imagick::CHANNEL_ALL);
    $img = $bg;
}

html

<img src="/round.php?i=/img/list_img.jpg&w=150&h=300&r=0&k=PNG&_off." />

标签: phpimagick

解决方案


推荐阅读