Я знаю, что уже немного поздно, но я искал во всей сети решение этой проблемы и не смог найти комплексное решение.Многие из постов, которые я нашел, касались редактирования изображения на пиксельной основе, что я не слишком любил делать.После объединения нескольких образцов с нескольких сайтов я пришел к следующему:
resizeCropPolygonImage ()
function resizeCropPolygonImage($source, $dest = null,
$newWidth = null, $newHeight = null, $startX = 0, $startY = 0,
$points = array(), $numCoords = 2) {
// Added in $numCoords in case we want to do 3D image processing in the future
// (currently we do not process anything other than 2D coordinates)
$points = array(100,115, 124,65, 192,65, 216,115, 192,165, 124,165);
$numPoints = count($points) / $numCoords;
// If there are not enough points to draw a polygon, then we can't perform any actions
if ($numPoints < 3) {
return;
}
// Get the original image's info
list($width, $height, $file_type) = getimagesize($source);
/******* Here I am using a custom function to resize the image *********
******* keeping the aspect ratio. *********
******* You'll have to add in your own re-sizing logic *********
// Resize the source (using dummy vars because we don't want our
// start x & y to be overwritten)
scaleDimensions($width, $height, $newWidth, $newHeight, $dummyX = null, $dummyY = null);
For simplicity sake, I'll just set the width and height to the new width and height
*************************************************************************/
$width = $newWidth;
$height = $newHeight;
switch ($file_type) {
case 1:
$srcImage = imagecreatefromgif($source);
if (function_exists(ImageGIF)) {
$imgType = "gif";
} else {
$imgType = "jpeg";
}
break;
case 2:
$srcImage = imagecreatefromjpeg($source);
$imgType = "jpeg";
break;
case 3:
$srcImage = imagecreatefrompng($source);
$imgType = "png";
break;
default:
return;
}
// Setup the merge image from the source image with scaling
$mergeImage = ImageCreateTrueColor($width, $height);
imagecopyresampled($mergeImage, $srcImage, 0, 0, 0, 0, $width, $height, imagesx($srcImage), imagesy($srcImage));
/******** This is probably the part that you're most interested in *******/
// Create the image we will use for the mask of the polygon shape and
// fill it with an uncommon color
$maskPolygon = imagecreatetruecolor($width, $height);
$borderColor = imagecolorallocate($maskPolygon, 1, 254, 255);
imagefill($maskPolygon, 0, 0, $borderColor);
// Add the transparent polygon mask
$transparency = imagecolortransparent($maskPolygon, imagecolorallocate($maskPolygon, 255, 1, 254));
imagesavealpha($maskPolygon, true);
imagefilledpolygon($maskPolygon, $points, $numPoints, $transparency);
// Apply the mask
imagesavealpha($mergeImage, true);
imagecopymerge($mergeImage, $maskPolygon, 0, 0, 0, 0, $width, $height, 100);
/******* Here I am using a custom function to get the outer *********
******* perimeter of the polygon. I'll add this one in below ********/
// Crop down to just the polygon area
$polygonPerimeter = getPolygonCropCorners($points, $numCoords);
$polygonX = $polygonPerimeter[0]['min'];
$polygonY = $polygonPerimeter[1]['min'];
$polygonWidth = $polygonPerimeter[0]['max'] - $polygonPerimeter[0]['min'];
$polygonHeight = $polygonPerimeter[1]['max'] - $polygonPerimeter[1]['min'];
// Create the final image
$destImage = ImageCreateTrueColor($polygonWidth, $polygonHeight);
imagesavealpha($destImage, true);
imagealphablending($destImage, true);
imagecopy($destImage, $mergeImage,
0, 0,
$polygonX, $polygonY,
$polygonWidth, $polygonHeight);
// Make the the border transparent (we're assuming there's a 2px buffer on all sides)
$borderRGB = imagecolorsforindex($destImage, $borderColor);
$borderTransparency = imagecolorallocatealpha($destImage, $borderRGB['red'],
$borderRGB['green'], $borderRGB['blue'], 127);
imagesavealpha($destImage, true);
imagealphablending($destImage, true);
imagefill($destImage, 0, 0, $borderTransparency);
if (!$dest) {
// If no dest was given, then return to browser
header('Content-Type: image/png');
imagepng($destImage);
} else {
// Output image will always be png
$dest .= '.png';
// Save to destination
imagepng($destImage, $dest);
}
// Destroy remaining images
imagedestroy($maskPolygon);
imagedestroy($srcImage);
imagedestroy($destImage);
// Only return a value if we were given a destination file
if ($dest) {
return $dest;
}
}
getPolygonCropCorners ()
function getPolygonCropCorners($points, $numCoords) {
$perimeter = array();
for ( $i = 0; $i < count($points); $i++ ) {
$axisIndex = $i % $numCoords;
if (count($perimeter) < $axisIndex) {
$perimeter[] = array();
}
$min = isset($perimeter[$axisIndex]['min']) ? $perimeter[$axisIndex]['min'] : $points[$i];
$max = isset($perimeter[$axisIndex]['max']) ? $perimeter[$axisIndex]['max'] : $points[$i];
// Adding an extra pixel of buffer
$perimeter[$axisIndex]['min'] = min($min, $points[$i] - 2);
$perimeter[$axisIndex]['max'] = max($max, $points[$i] + 2);
}
return $perimeter;
}
Используя эту функцию, я могу превратить это изображение
в это
Возможно, он не полностью завершен, но я думаю, что это определенно хорошая отправная точка.
РЕДАКТИРОВАТЬ
- 09/19 / 2014 - добавлена прозрачностьдо границы