Я знаю, что немного поздно, но я искал по всему Интернету решение этой проблемы и не мог найти решение «все-в-одном». Многие из сообщений, которые я нашел, включали редактирование изображения на пиксельной основе, которое я не слишком любил делать. После склеивания нескольких образцов из нескольких сайтов, вот что я придумал:
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;
}
Используя эту функцию, я могу поверните это изображение
в этот один
Это не может быть полностью завершена, но я думаю, что это, безусловно, хорошо, начиная от точки.
EDIT
- 09/19/2014 - Добавлена прозрачность до границы
пожалуйста попытаться сделать старт, и когда застрявший почтовый индекс. –
Учитывая, что PHP не является графическим языком, вам нужно дать нам понять, как вы пытаетесь отобразить этот «многоугольник». Вы пытаетесь создать изображение? Если да, то какое расширение вы используете? Вы пытаетесь сделать это с помощью CSS? Пожалуйста, уточните, что именно вы ожидаете от конечного результата и где вы ожидаете его видимости. – DaveRandom
Хорошо, чтобы прояснить следующий пример: http://www.chipwreck.de/blog/software/cwcrop/cwcrop-demo/. Теперь я не хочу, чтобы область света была обрезана, но затемненная. Кроме того, это не должен быть прямоугольник, а многоугольник. Затем результат должен быть объединен с другим изображением (я уже знаю, как это сделать). – Jan