注:
我想通过将背景图像与多边形和一些文本放在一起来创建自定义图形。
输入背景图像具有不同的尺寸和纵横比,但最终图形必须具有固定的(2:1)纵横比(它也必须具有预定义的尺寸,但调整图像大小是微不足道的,所以正确的宽高比是我唯一的目标)。
目前,我通过使用 imagecrop
函数执行 最大中心区域裁剪
,将输入图像裁剪为适合目标宽高比 (2:1)。此后,我使用
imagefilledpolygon
方法在其上绘制红色多边形,如下所示(忽略红色带上绘制的文本)[下面的裁剪屏幕截图仅用于演示目的,实际上是通过imagecrop
函数以编程方式完成的]这是我绘制叠加层的函数(在将图像裁剪为 2:1 宽高比完成后调用此函数)
/**
* adds overlay (colored band) on the image
* for better output, overlay must be added before resizing
*/
public function withOverlay(): NotifAdsCreativeGenerator {
// Prepare custom red-color Hex to RGB https://stackoverflow.com/a/15202130/3679900
list($r, $g, $b) = sscanf(self::OVERLAY_COLOR, "#%02x%02x%02x");
$custom_red_color = imagecolorallocate($this->getCrrImage(), $r, $g, $b);
// prepare coordinates for polygon
$coords = [
[0, 0],
[(int) ($this->getCrrWidth() * self::OVERLAY_BEGIN_X_RATIO), 0],
[(int) ($this->getCrrWidth() * self::OVERLAY_END_X_RATIO), $this->getCrrHeight()],
[0, $this->getCrrHeight()]
];
$flattened_coords = array_merge(...$coords);
// draw polygon on image
imagefilledpolygon($this->getCrrImage(), $flattened_coords, count($flattened_coords) / 2, $custom_red_color);
return $this;
}
(1.28:1),但我无法找到在图像边界之外绘制多边形的方法(在此过程中有效地扩展图像)。有没有办法使用 PHP-GD 库来做到这一点?
使用
imagecreatetruecolor
函数创建所需尺寸(以及 2:1 目标纵横比)的 空“画布”图像(在
imagecopy
方法将图像复制到画布右侧(必须完成一些基本数学计算以确定图像必须放置在画布上的偏移量)现在和以前一样,可以在画布的左侧绘制红色多边形以获得最终图形
/**
* adds overlay (colored band) on the image
* for better output, overlay must be added before resizing
*
* This method tries to preserve maximum center region of input image by performing minCenterCrop(.) on it
* before drawing an overlay that extends beyond left border of the cropped image
*
* (since this method incorporates call to 'withMinCenterCrop', calling that method before this is not required
* (and is redundant). For benefits of this method over 'withOverlay', read docstring comment of
* 'withMinCenterCrop' method
* @return NotifAdsCreativeGenerator
*/
public function withExtendedOverlay(): NotifAdsCreativeGenerator {
// perform min center crop to the 1.28:1 aspect ratio (preserve max central portion of image)
$this->withMinCenterCrop();
// this $required_canvas_aspect_ratio calculates to 2.0 (2:1 aspect ratio)
// calculate aspect ratio & dimensions of empty 'canvas' image
// since canvas is wider than min center-cropped image (as space on the left will be occupied by red overlay)
// therefore it's height is matched with cropped image and width is calculated
$required_canvas_aspect_ratio = self::IMAGE_WIDTH / self::IMAGE_HEIGHT;
// height of cropped image
$canvas_height = $this->getCrrHeight();
$canvas_width = $required_canvas_aspect_ratio * $canvas_height;
// create a new 'canvas' (empty image) on which we will
// 1. draw the existing input 'min-cropped' image on the right
// 2. draw the red overlay on the left
$canvas_image = imagecreatetruecolor($canvas_width, $canvas_height);
// copy contents of image on right side of canvas
imagecopy(
$canvas_image,
// cropped image
$this->getCrrImage(),
self::OVERLAY_BEGIN_X_RATIO * $canvas_width,
0,
0,
0,
// dimensions of cropped image
$this->getCrrWidth(),
$this->getCrrHeight()
);
// draw red band overlay on left side of canvas
$this->crr_image = $canvas_image;
return $this->withOverlay();
}