1

我注意到有一些脚本要尝试执行此操作,但没有一个非常适合我的情况。

我拼凑了一些我发现尝试提出正确解决方案的脚本。

但是我现在遇到了2个问题。

  1. 图像未居中。
  2. 三角形的边长不相等。

该演示位于http://owenmelbourne.com/triangle.php

代码是

$src = imagecreatefromjpeg ('http://uat.eruptedevents.secureping.co.uk/media/images/upload/1200/154.jpg');
// Get image width/height

$srcWidth   = imagesx ($src);
$srcHeight  = imagesy ($src);

// Get centre position

$centreX    = floor ($srcWidth / 2);
$centreY    = floor ($srcHeight / 2);

// Set new image size and start x/y

$destWidth  = $srcWidth;
$destHeight = $srcHeight;

$destSX     = 0;
$destSY     = $centreY;

// Create the image
$square = 500;

if( $srcWidth >= $srcHeight ){
    $square = $srcHeight;
}
else {
    $square = $srcWidth;
}
$shift = array ("left" => 0, "top" => 0);

$shift["left"] = ( $srcWidth / 4 ) * -1;
$shift["top"] = ( $srcHeight / 4 ) * -1;

$dest   = imagecreatetruecolor ($square, $square);

// Copy from source
imagecopy ($dest, $src, $shift["left"], $shift["top"], 0, 0, $destWidth, $destHeight);

// OK... we now have the correctly sized rectangle copied over from the source image
// Lets cut it down and turn it into the triangle we want by removing the other triangles
// We remove the area by defining another colour as transparent and creating shapes with that colour

$colRed  = imagecolorallocatealpha ($dest, 255, 0, 0, 0);
$blue  = imagecolorallocatealpha ($dest, 0, 0, 244, 0);
imagecolortransparent ($dest, $colRed);

$sidelength = $square;

imagefilledpolygon ($dest, array (
                    0, 0,
                    $square/2, 0,
                    0, $square
                    ), 3, $colRed);
imagefilledpolygon ($dest, array (
                    $square, 0,
                    $square, $square,
                    $square/2, 0
                    ), 3, $colRed);

$dest2   = imagecreatetruecolor ($square, $square);

// Output new image

header ('Content-Type: image/png');
imagepng ($dest);

// Clean up

imagedestroy ($thumbNail);
imagedestroy ($dest);

我将如何从中间进行完美的三角形裁剪,并将其作为图像返回?

非常感谢

4

2 回答 2

2

矩形中的等边三角形

对,假设您想要一个矩形内的最大尺寸等边三角形,其平面平行于水平轴,即。最上面的点,那么根据矩形的纵横比有两种情况。


横向矩形(宽度 > 高度)

矩形中的等边三角形 - 横向

在这种情况下,矩形的高度是限制因素。

任务是确定三角形边的长度,并用它找到三角形的两个底点的位置,方法是从矩形的中点取一半的长度。

如果我们将三角形长度e称为图上标记的(也是gf),并且矩形的高度标记为a,那么快速的三角函数说明:

sin 60 = opp / hyp = a / e = sqrt(3) / 2

所以

e = 2a / sqrt(3)

我们可以称之为b图中的水平边,中点显然在b / 2,所以三角形底边的点在[ (b / 2) ± (e / 2) , 0 ]

要执行裁剪,请执行以下步骤:

  1. 创建一个与源大小相同的新图像
  2. 填充整个目的地透明
  3. 从三角形的两个基点之间的源复制一个矩形,全高,到目标的相同位置
  4. 从三角形的两个基点到矩形的顶部,在两侧填充透明的三角形,在它们上方平行于矩形顶部的中点

纵向矩形(宽度 < 高度)

矩形中的等边三角形 - 纵向

在这种情况下,宽度是限制因素。

因此三角形边的长度就是矩形的宽度,所以这是已知的。需要计算的是三角形的高度。

H如果我们调用图中标记的高度和b前面的宽度,那么简单的三角函数表示:

sin 60 = opp / hyp = H / b = sqrt(3) / 2

所以

H = b x sqrt(3) / 2

我们可以称之为图中的垂直边a,中点在a / 2,所以三角形底边的点在[ 0 , (a / 2) + (H / 2) ][ b , (a / 2) + (H / 2) ],三角形的尖端E[ (b / 2) , (a / 2) - (H / 2) ]

要执行裁剪,请执行以下步骤(最初与之前的两个步骤相同):

  1. 创建一个与源大小相同的新图像
  2. 填充整个目的地透明
  3. 将三角形底部和尖端之间的全宽源中的矩形复制E到目标中的相同位置
  4. E从三角形的两个基点到三角形尖端到与所讨论三角形的基点相同的高度相同的边缘上的点,在E两边都用透明填充三角形

注意。在你有一个正方形的情况下,任何一种计算都应该有效,尽管景观计算对我来说似乎更简单,所以我会使用它。


代码

改编自你自己的,所以不是我通常的编码风格,但它有效。花了一段时间,因为透明度在 GD 中有点痛苦。

原来的

Junior Gorg 与灯笼

裁剪 (使用下面的代码创建)

Junior Gorg 带灯笼 - 三角形裁剪

<?php

// Acquire image

$src = imagecreatefromjpeg ('http://i.stack.imgur.com/YlnCJ.jpg');

// Get image width/height

$srcWidth   = imagesx ($src);
$srcHeight  = imagesy ($src);

// Get centre position

$centreX    = floor ($srcWidth / 2);
$centreY    = floor ($srcHeight / 2);

// Calculate triangle length (base) and points

if ( $srcWidth >= $srcHeight ) {
    $base = (2 * $srcHeight) / sqrt(3);
    $points = array( 'a' => array( 'x' => $centreX - ( $base / 2 ),
                                   'y' => $srcHeight ),
                     'b' => array( 'x' => $centreX + ( $base / 2 ),
                                   'y' => $srcHeight ),
                     'c' => array( 'x' => $centreX,
                                   'y' => 0 ) );
} else {
    $base = $srcWidth;
    $height = $base * sqrt(3) / 2;
    $points = array( 'a' => array( 'x' => 0,
                                   'y' => $centreY + ( $height / 2 ) ),
                     'b' => array( 'x' => $srcWidth,
                                   'y' => $centreY + ( $height / 2 ) ),
                     'c' => array( 'x' => $centreX,
                                   'y' => $centreY - ( $height / 2 ) ) ); 
}

// Create destination, same size as source

$dest = imagecreatetruecolor ($srcWidth, $srcHeight);

// Setup full alpha handling for pngs (8-bit)
imagealphablending ($dest, false);
imagesavealpha ($dest, true);

// Define a transparent colour

$colTrans  = imagecolorallocatealpha ($dest, 255, 255, 255, 127);

// If old png transparency was used, setting the transparency colour
// would be needed, with 8-bit it is not
// imagecolortransparent ($dest, $colTrans);

// Make the image transparent

imagefill ($dest, 0, 0, $colTrans);

// Copy from source just the rectangle flush with the triangle

imagecopy ($dest, $src, // Images
           $points['a']['x'], $points['c']['y'], // Destination x,y
           $points['a']['x'], $points['c']['y'], // Source x,y
           $points['b']['x'] - $points['a']['x'], // Width
           $points['a']['y'] - $points['c']['y']); // Height

// Fill out the triangles within that area not wanted with transparent

// Left side

imagefilledpolygon ($dest, array( $points['a']['x'], $points['a']['y'],
                                  $points['c']['x'], $points['c']['y'],
                                  $points['a']['x'], $points['c']['y'] ),
                    3, $colTrans);

// Right side

imagefilledpolygon ($dest, array( $points['b']['x'], $points['b']['y'],
                                  $points['c']['x'], $points['c']['y'],
                                  $points['b']['x'], $points['c']['y'] ),
                    3, $colTrans);

// Output new image

header ('Content-Type: image/png');

imagepng ($dest);

// Clean up

imagedestroy ($src);
imagedestroy ($dest);
于 2013-06-11T19:31:47.477 回答
0

ImageArtist是 GD 的一个包装器,可以让我编写的开发人员更轻松。您可以使用它来创建任何类型的多边形

 $triangle = new Triangle("http://i.stack.imgur.com/YlnCJ.jpg");
 $triangle->setPointA(50,0,true);
 $triangle->setPointB(100,100,true);
 $triangle->setPointC(0,100,true);
 $triangle->build();
 $triangle->dump(); //this is for debugging only read documentation for more operations

最终输出看起来像这样

在此处输入图像描述

于 2017-09-10T14:46:23.110 回答