php生成海报
发表于:2024-04-16 14:12:12浏览:163次
前言
本文将详细介绍如何使用php生成海报,并提供整理的源码和通过示例代码进行说明。
一、了解画布坐标
画布坐标是以“最左上角”开始作为坐标的起点。要在画布上面哪个添加图片、文字等都是通过坐标来定位。
我们把每个要添加的文字或图片称为元素,每个元素的“最左上角”为坐标开始的点。
开始编码
<?php
namespace app\common\utils;
/**
* 生成海报
* 需安装扩展:exif
*/
class Poster
{
protected $bg;
protected $font;
protected $images = [];
public function __construct($options = [])
{
$this->font = $options['font'] ?? ROOT_PATH . 'public' . DS . 'assets'. DS .'fonts'. DS . 'SourceHanSansOLD-Light-2.otf';
}
/**
* 设置背景图
* @param $path
* @return $this
*/
public function setBg($path)
{
$this->bg = $this->createImage($path);
return $this;
}
/**
* 渲染文字
* @param $text
* @param $x
* @param $y
* @param $rgb
* @param $size
* @return $this
*/
public function setText($text,$x,$y,$rgb = '0,0,0',$size = 18)
{
$rgb = explode(',',$rgb);
$color = imagecolorallocate($this->bg, $rgb[0],$rgb[1],$rgb[2]);
imagettftext($this->bg, $size, 0, $x, $y, $color, $this->font, $text);
return $this;
}
/**
* 渲染图片
* @param $path
* @param $x
* @param $y
* @param $width
* @param $height
* @return $this
*/
public function setImage($path,$x,$y,$width = null,$height = null)
{
$image = $this->createImage($path);
$image = $this->notRotate($image,$path);
if (!is_null($width) && !is_null($height)) {
$image = $this->editSize($image,$width,$height);
}
else {
$width = imagesx($image);
$height = imagesy($image);
}
imagecopy($this->bg, $image, $x, $y, 0, 0, $width, $height);
array_push($this->images,$image);
return $this;
}
/**
* 生成
* @param $savename
* @return void
*/
public function build($savename = null)
{
$image = $this->getBg();
if (is_null($savename)) {
$savename = 'poster.png';
// 禁用PHP输出缓冲
ob_end_clean();
// 发送合适的头部信息
header('Content-Type: image/png');
header('Content-Disposition: inline; filename="'.$savename.'"');
$suffix = $this->getSuffix($savename);
$savename = null;
}
else {
$suffix = $this->getSuffix($savename);
}
switch ($suffix){
case 'png':
imagepng($image,$savename);
break;
case 'jpg':
case 'jpeg':
imagejpeg($image,$savename);
break;
case 'webp':
imagewebp($image,$savename);
break;
case 'gif':
imagegif($image,$savename);
break;
case 'bmp':
imagebmp($image,$savename);
break;
}
$this->destroy();
}
/**
* 获取后缀
* @param $str
* @return string
*/
private function getSuffix($str)
{
return strtolower(substr(strrchr($str,'.'),1));
}
/**
* 获取背景图
* @return mixed
*/
private function getBg()
{
return $this->bg;
}
/**
* 修改图片尺寸
* @param $image
* @param int $new_width
* @param int $new_height
* @return false|\GdImage|resource
*/
private function editSize($image,int $new_width,int $new_height)
{
// 获取原始尺寸
$width = imagesx($image);
$height = imagesy($image);
// 创建目标图片
$new_image = imagecreatetruecolor($new_width, $new_height);
// 调整图片分辨率
imagecopyresampled(
$new_image,
$image,
0,
0,
0,
0,
$new_width,
$new_height,
$width,
$height
);
return $new_image;
}
/**
* 旋转回正
* EXIF 信息只在 JPG 、 TIFF 等类型的图片格式中存在,所以 PNG 图片是无法获取到 EXIF 信息的。
* 如果对 PNG 图片使用 exif_read_data() 就会报出警告。而对于 JPG 来说,就会返回完整的全部的 EXIF 内容。
* @param $image
* @param $image_path
* @return false|\GdImage|mixed|resource
*/
private function notRotate($image,$image_path)
{
if (!in_array($this->getSuffix($image_path),['jpg','jpeg'])) {
return $image;
}
$exif = exif_read_data($image_path);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']) {
case 8: // 水平翻转
$image = imagerotate($image, 90, 0);
break;
case 3: // 180度旋转
$image = imagerotate($image, 180, 0);
break;
case 6: // 垂直翻转
$image = imagerotate($image, -90, 0);
break;
}
}
return $image;
}
/**
* 创建图片对象
* @param $image_path
* @return false|\GdImage|resource
*/
private function createImage($image_path)
{
$suffix = pathinfo($image_path,PATHINFO_EXTENSION);
switch ($suffix){
case 'png':
$image = imagecreatefrompng($image_path);
break;
case 'jpg':
case 'jpeg':
$image = imagecreatefromjpeg($image_path);
break;
case 'webp':
$image = imagecreatefromwebp($image_path);
break;
case 'gif':
$image = imagecreatefromgif($image_path);
break;
case 'bmp':
$image = imagecreatefrombmp($image_path);
break;
}
return $image;
}
/**
* 销毁资源/释放内存
* @return void
*/
private function destroy()
{
$images = $this->images;
if ($images) {
foreach ($images as $image) {
imagedestroy($image);
}
}
}
}
// 调用
$ps = new \app\common\utils\Poster();
$ps->setBg(ROOT_PATH . 'public' . DS . 'assets'. DS. 'img'. DS . 'cert-bg.png')
->setText('你好:李四',600,303,'255,90,90')
->setImage(ROOT_PATH . 'public' . DS . 'assets'. DS. 'img'. DS . 'signet1.png',760,420)
->setImage(ROOT_PATH . 'public' . DS . 'assets'. DS. 'img'. DS . 'signet2.png',500,420)
->build(ROOT_PATH . 'public' . DS . 'poster_test.png');
栏目分类全部>