Обрезать изображение из центра PHP - PullRequest
12 голосов
/ 31 июля 2011

Я хочу обрезать изображение от центра размером 200 * 130, обрезаемое изображение может различаться по размеру, если изображение меньше, мы не обрежем его, я знаю, как сделать эту часть, где я могу проверить высоту и с помощью изображения, но отчасти ударил в обрезку с середины изображения Как я не могу понять, как сохранить центр в качестве точки обрезки и чем обрезать его наружу

Ответы [ 4 ]

33 голосов
/ 01 августа 2011

GD поставляется в комплекте со всеми установками PHP начиная с версии 4.3.6, так что скорее всего, у вас это есть.

Вот шаги, которые вам нужно предпринять ...

  1. Создатьресурс изображения с использованием одной из функций GD imagecreatefrom*().То, что вы используете, зависит от типа изображения, с которым вы имеете дело *
  2. . Определите размеры изображения, используя imagesx() и imagesy()
  3. Определите ваши координаты кадрирования, используя следующий алгоритм, и кадрируйте, используя imagecopy()

Найдите координаты кадрирования

$width  = imagesx($img);
$height = imagesy($img);
$centreX = round($width / 2);
$centreY = round($height / 2);

$cropWidth  = 200;
$cropHeight = 130;
$cropWidthHalf  = round($cropWidth / 2); // could hard-code this but I'm keeping it flexible
$cropHeightHalf = round($cropHeight / 2);

$x1 = max(0, $centreX - $cropWidthHalf);
$y1 = max(0, $centreY - $cropHeightHalf);

$x2 = min($width, $centreX + $cropWidthHalf);
$y2 = min($height, $centreY + $cropHeightHalf);

Не стесняйтесь использовать мой класс манипуляции изображениями, это должно облегчить некоторые аспекты - https://gist.github.com/880506

$im = new ImageManipulator('/path/to/image');
$centreX = round($im->getWidth() / 2);
$centreY = round($im->getHeight() / 2);

$x1 = $centreX - 100;
$y1 = $centreY - 65;

$x2 = $centreX + 100;
$y2 = $centreY + 65;

$im->crop($x1, $y1, $x2, $y2); // takes care of out of boundary conditions automatically
$im->save('/path/to/cropped/image');
5 голосов
/ 16 апреля 2018

Обрезка изображения с настраиваемым выравниванием

Вот собственная реализация функции (называемой cropAlign), которая может обрезать изображение до заданной ширины и высоты с выравниванием до 9.стандартные точки (4 ребра, 4 угла, 1 центр).

Alignment points

Просто передайте изображение, нужный размер кадрирования и выравнивание подве оси (вы можете использовать left, center, right или top, middle, bottom независимо от оси) для функции cropAlign.

Спецификация

Описание

cropAlign(resource $image, int $width, int $height, string $horizontalAlign = 'center', string $verticalAlign = 'middle')

Параметры

  • image: ресурс изображения,возвращается одной из функций создания изображения, например imagecreatetruecolor().
  • width: ширина окончательного обрезанного изображения.
  • height: высота окончательного обрезанного изображения.
  • horizontalAlign: где культура должна быть выровнена вдоль горизонтальной оси.Возможные значения: left / top, center / middle, right / bottom.
  • verticalAlign: где выровнять урожайвдоль вертикальной оси.Возможные значения: left / top, center / middle, right / bottom.

Возвращаемые значения

Возврат ресурса обрезанного изображения вуспех или FALSE при неудаче.Это происходит от imagecrop().

Исходный код

function cropAlign($image, $cropWidth, $cropHeight, $horizontalAlign = 'center', $verticalAlign = 'middle') {
    $width = imagesx($image);
    $height = imagesy($image);
    $horizontalAlignPixels = calculatePixelsForAlign($width, $cropWidth, $horizontalAlign);
    $verticalAlignPixels = calculatePixelsForAlign($height, $cropHeight, $verticalAlign);
    return imageCrop($image, [
        'x' => $horizontalAlignPixels[0],
        'y' => $verticalAlignPixels[0],
        'width' => $horizontalAlignPixels[1],
        'height' => $verticalAlignPixels[1]
    ]);
}

function calculatePixelsForAlign($imageSize, $cropSize, $align) {
    switch ($align) {
        case 'left':
        case 'top':
            return [0, min($cropSize, $imageSize)];
        case 'right':
        case 'bottom':
            return [max(0, $imageSize - $cropSize), min($cropSize, $imageSize)];
        case 'center':
        case 'middle':
            return [
                max(0, floor(($imageSize / 2) - ($cropSize / 2))),
                min($cropSize, $imageSize),
            ];
        default: return [0, $imageSize];
    }
}

Пример использования

Вот несколько примеров обрезки с использованием это изображение чайника Юта .

$im = imagecreatefrompng('https://i.stack.imgur.com/NJcML.png');
imagePng(cropAlign($im, 200, 250, 'center', 'middle'));
imagePng(cropAlign($im, 300, 150, 'left', 'top'));
imagePng(cropAlign($im, 1000, 250, 'right', 'middle'));

Вход

Example input: Utah teapot

Выход

cropAlign($im, 200, 250, 'center', 'middle')

Output #1

cropAlign($im, 300, 150, 'left', 'top')

Output #2

cropAlign($im, 1000, 250, 'right', 'middle')

Output #3

2 голосов
/ 03 мая 2017

Боже, почему ты делаешь это нелегко?Просто установите позиции x и y в качестве суммы для обрезки / 2

   $imageSize = getimagesize('thumbnail.png');

$croppedImage = imagecrop(imagecreatefrompng('thumbnail.png'), ['x' => 0, 'y' => ($imageSize[1]-$imageSize[0]*(9/16))/2, 'width' => $imageSize[0], 'height' =>  $imageSize[0]*(9/16)]);

обратите внимание, как я использовал свой $ imageSize [0] * (9/16), то есть сумму, которую я обрезаю внаправление y, и я вычел это из высоты исходного изображения, чтобы найти количество кадрирования, а затем разделил на 2. Если вы хотите сделать то же самое для ширины, просто выполните те же шаги.

0 голосов
/ 31 июля 2011

Это может помочь вам.

function cropCentered($img, $w, $h)
{
  $cx = $img->getWidth() / 2;
  $cy = $img->getHeight() / 2;
  $x = $cx - $w / 2;
  $y = $cy - $h / 2;
  if ($x < 0) $x = 0;
  if ($y < 0) $y = 0;
  return $img->crop($x, $y, $w, $h);
}

Я предполагаю, что вы используете библиотеку GD.$ img - это GD-изображение, $ w и $ h - ширина и высота, соответственно, вы хотите, чтобы ваше новое изображение имело.В вашем случае, $ w = 200, $ h = 130.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...