从中心 PHP 裁剪图像

Posted

技术标签:

【中文标题】从中心 PHP 裁剪图像【英文标题】:Crop Image From Center PHP 【发布时间】:2011-07-31 18:15:37 【问题描述】:

我想从中心裁剪尺寸为 200 * 130 的图像要裁剪的图像的大小可能会有所不同,如果图像较小,我们不会裁剪它我知道如何在这部分中检查高度并使用图像,但有点像从图像中间裁剪的东西 因为我无法弄清楚如何将中心保持为裁剪点而不是向外裁剪它

【问题讨论】:

【参考方案1】:

GD 与 4.3.6 版以后的所有 php 安装捆绑在一起,所以很有可能,你拥有它。

这是您需要采取的步骤...

    使用 GD imagecreatefrom*() 函数之一创建图像资源。您使用哪一种取决于您处理的图像类型 使用imagesx()imagesy() 确定图像尺寸 使用以下算法确定裁剪坐标并使用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');

【讨论】:

在第一个算法中,哪些变量会对应 imagecopy() 的正确参数? @ChrisHarrison 见gist.github.com/philBrown/880506#file-imagemanipulator-php-L185 @Phil 使用你的库。谢谢!【参考方案2】:

可配置对齐方式的图像裁剪

这是一个函数(称为cropAlign)的原生实现,它可以将图像裁剪为给定的宽度和高度,并对齐到 9 个标准点(4 个边、4 个角、1 个中心)。

只需传递图像,裁剪所需的大小,以及两个轴上的对齐方式(您可以使用leftcenterrighttopmiddlebottom 无关紧要从轴)用于cropAlign 函数。

规格

说明

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

参数

image:图片资源,由图片创建函数之一返回,如imagecreatetruecolor()width:最终裁剪图像的宽度。 height:最终裁剪图像的高度。 horizontalAlign:裁剪应沿水平轴对齐的位置。可能的值为:left/topcenter/middleright/bottomverticalAlign:裁剪应沿垂直轴对齐的位置。可能的值为:left/topcenter/middleright/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];
    

示例用法

以下是使用this image 的Utah teapot 的一些裁剪示例。

$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'));

输入

输出

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

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

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

【讨论】:

真的很棒,更实用 谢谢,很舒服【参考方案3】:

天哪,你为什么要这么辛苦?只需简单地将 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. 如果你想对宽度做同样的事情,只需按照相同的步骤。

【讨论】:

【参考方案4】:

这可能会对你有所帮助。

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。

【讨论】:

不,我没有可用的 GD 库 @June GD 包含在大多数 php 安装中,使用 phpinfo() 你很可能会看到它 你能帮我在上面创建没有 GD 库并保存图像吗? 由于我不知道 Gd 库,我收到此错误致命错误:在 /home/content/12/7942812/html/contest/GdPHPCrop 中的非对象上调用成员函数 getWidth() .php 在第 4 行,所以我想远离 GD 什么是“GD 图像”?所有 GD 创建函数都返回一个资源标识符。 AFAIK,没有开箱即用的面向对象的 GD 接口

以上是关于从中心 PHP 裁剪图像的主要内容,如果未能解决你的问题,请参考以下文章

PHP图像调整大小和裁剪功能

我需要一些帮助在 PHP (GD) 中裁剪图像

PHP:图像调整大小和裁剪为纵向

从顶部裁剪,而不是从中心裁剪

PHP GD - 围绕任何给定点裁剪图像

使用 php 从图像中裁剪多边形