web-dev-qa-db-ja.com

中央から画像を切り抜くPHP

中央から200 * 130のサイズで画像をトリミングしたいです。トリミングする画像のサイズは異なる場合があります。画像が小さい場合はトリミングしません。この部分で画像の高さと画像を確認できますが、画像の真ん中からトリミングすることにちょっとぶつかりました。中心をトリミングポイントとして維持する方法がわからないので、外側にトリミングするよりも

12
June

Gdには、バージョン4.3.6以降のすべてのPHPインストールがバンドルされているため、可能性はあります。

実行する必要のある手順は次のとおりです...

  1. Gd imagecreatefrom*() 関数の1つを使用して画像リソースを作成します。使用する画像は、扱っている画像の種類によって異なります。
  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');
33
Phil

設定可能な配置による画像の切り抜き

これは、関数(cropAlignと呼ばれる)のネイティブ実装であり、は、alignを使用して、指定された幅と高さに画像をトリミングできます9つの標準ポイント(4つのエッジ、4つのコーナー、1つのセンター)。

Alignment points

画像、切り抜きの希望のサイズ、および2つの軸上の配置を渡すだけです(leftcenterright、またはtopを使用できます、middlebottom軸に関係なく)cropAlign関数の場合。

仕様

説明

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

パラメーター

  • imageimagecreatetruecolor()などの画像作成関数の1つによって返される画像リソース
  • width:最終的にトリミングされた画像の幅。
  • height:最終的にトリミングされた画像の高さ。
  • horizontalAlign:作物を横軸に沿って配置する場所。可能な値は次のとおりです:left/topcenter/middleright/bottom
  • verticalAlign:作物を垂直軸に沿って配置する場所。可能な値は次のとおりです: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];
    }
}

使用例

ユタティーポットこの画像 を使用したいくつかの作物の例を次に示します。

$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

5
totymedli

うわあ、なぜあなたはそれを難し​​い方法でやっているのですか? 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で割った場合。幅についても同じことをしたい場合は、同じ手順に従ってください。

2
Ethan SK

これはあなたを助けるかもしれません。

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です。

0
P. R. Ribeiro