PHP 生成分享海报

news2024/11/29 19:43:00

因为用户端有多个平台,如果做分享海报生成,需要三端都来做,工作量比较大。

所以这个艰巨的任务就光荣的交给后端了。经过一定时间的研究和调试,最终圆满完成了任务,生成分享海报图片实现笔记如下。

目录

准备字体文件

准备海报的图片素材

创建图片

调用

海报截图

总结


准备字体文件

字体文件需与设计图字体保持一致,所以需要下载使用相同的字体文件,否则效果肯定

不符合设计。这里实现使用的是阿里普惠体,下载到项目静态文件路径中,以备调用。

字体文件如下:

准备海报的图片素材

在真实的业务中,海报所需的图片素材来自于活动、商品、用户、小程序码,直接去准备相应的素材即可。在demo中使用了固定的图片素材。

如下:

创建图片

创建图片使用了PHP语言GD库的画图函数。

为方便调用和修改,已经将参数和最终方法进行了封装调用。

具体代码如下:

// 字体
const FONT = '/font/AlibabaPuHuiTi-3-55-Regular.ttf';
const FILEPATH = './test.png';


/**
 * 获取字体全路径
 * @return string
 */
function getFont()
{
    return dirname(__FILE__) . FONT;
}

/**
 * 生成活动分享海报
 */
function activity_poster()
{
    // 使用参数
    $param = [
        'id'            =>  1,  //活动id
        'title'         =>  '活动标题活动标题活动标题', //活动标题
        'text'          =>  '活动描述活动描述活动描述活动描述活动描述活动描述活动描述活动描述活动描述活动描述活动描述活动描述', // 活动描述
        'member_nick'   =>  '一个高尚的人,一个脱落了低级趣味的人', // 团长昵称
        'member_image'  =>  './img/head.png', // 团长头像
        'createTime'    =>  date('m/d H:i:s', time()), // 分享时间
        'cover'         =>  './img/big.png', // 封面图片
        'mini_logo_img' =>  './img/qr.png', // 小程序码
        'price'         =>  100,
        'mini_bg'       =>  './img/min_bg.png'
    ];

    $refer_qrcode_logo = createPoster($param);
    if (file_exists($refer_qrcode_logo)) {
        echo FILEPATH;die;
    } else {
        echo '创建失败';
    }
}

/**
 * 创建海报
 * @param $param
 * @return string
 */
function createPoster($param)
{
    $font = getFont();
    // 存储图片路径
    $refer_qrcode_logo = FILEPATH;
    // 判断是否已生成海报
    if (!file_exists($refer_qrcode_logo)) {
        // 创建一个白色背景图
        $back_width = 530;
        $back_height = 1000;

        $t_logo2 = imagecreatetruecolor($back_width, $back_height);
        $background2 = imagecolorallocate($t_logo2, 255, 255, 255);
        imagefill($t_logo2, 0, 0, $background2);

        // 定义边距
        $left = 30;
        $top = 26;

        $textcolor = imagecolorallocate($t_logo2, 24, 24, 24);
        $textcolor2 = imagecolorallocate($t_logo2, 189, 189, 189);
        $textcolor3 = imagecolorallocate($t_logo2, 165, 165, 165);
        $textRed = imagecolorallocate($t_logo2, 254, 48, 49);

        // 团长头像
        $head_width = 64;
        $head_height = 64;
        $member_image = imagecreatefromstring(file_get_contents($param['member_image']));
        $source_info = getimagesize($param['member_image']);
        imagecopyresampled($t_logo2, $member_image, $left, $top, 0, 0, $head_width, $head_height, $source_info[0], $source_info[1]);

        // 团长昵称
        $nick_x = 106;
        $nick_y = 56;
        // 昵称过长处理
        $member_nick = $param['member_nick'];
        if (mb_strlen($member_nick) > 12) {
            $member_nick = mb_substr($member_nick, 0, 12) . '...';
        }
        imagefttext($t_logo2, 20, 0, $nick_x, $nick_y, $textcolor, $font, mb_convert_encoding($member_nick, 'html-entities', 'UTF-8'));

        // 分享时间
        $time_x = 106;
        $time_y = 85;
        imagefttext($t_logo2, 18, 0, $time_x, $time_y, $textcolor2, $font, mb_convert_encoding($param['createTime'], 'html-entities', 'UTF-8'));

        // 封面
        $cover_width = 470;
        $cover_height = 516;
        $cover_y = 110;
        $logo = imagecreatefromstring(file_get_contents($param['cover']));
        $source_info = getimagesize($param['cover']);
        imagecopyresampled($t_logo2, $logo, $left, $cover_y, 0, 0, $cover_width, $cover_height, $source_info[0], $source_info[1]);

        // 活动标题
        $y = 642;
        $line_split = 5;
        $goods_name_size = 30;
        $title_width = $back_width - ($left * 2);

        // 换行处理
        $text_array = draw_txt_to(array('fontsize' => $goods_name_size, 'width' => $title_width, 'left' => 0), $param['title']);
        foreach ($text_array as $text) {
            $y += $goods_name_size + $line_split;
            imagefttext($t_logo2, $goods_name_size, 0, $left, $y, $textcolor, $font, mb_convert_encoding($text, 'html-entities', 'UTF-8'));
        }

        // 活动描述
        $y += 20;
        $line_split = 5;
        $goods_name_size = 18;
        $desc_width = $back_width - ($left * 2);

        // 换行处理
        if ($param['text']) {
            $text_array = draw_txt_to(array('fontsize' => $goods_name_size, 'width' => $desc_width, 'left' => 0), $param['text']);
            foreach ($text_array as $text) {
                $y += $goods_name_size + $line_split;
                imagefttext($t_logo2, $goods_name_size, 0, $left, $y, $textcolor3, $font, mb_convert_encoding($text, 'html-entities', 'UTF-8'));
            }
        }

        // 价格
        $goods_name_size = 28;
        $priceY = $back_height - $goods_name_size - 61 - 40;
        $text = '¥' . $param['price'];
        imagefttext($t_logo2, $goods_name_size, 0, $left, $priceY, $textRed, $font, mb_convert_encoding($text, 'html-entities', 'UTF-8'));

        // 二维码
        $logo_size = 200;
        $logo_x = 314;
        $logo_y = $back_height - $logo_size - 15;
        $logo = imagecreatefromstring(file_get_contents($param['mini_logo_img']));
        $source_info = getimagesize($param['mini_logo_img']);
        imagecopyresampled($t_logo2, $logo, $logo_x, $logo_y, 0, 0, $logo_size, $logo_size, $source_info[0], $source_info[1]);

        /*$text = '长按识别小程序 跟团购买';
        $goods_name_size = 10;
        $left_top = $y + ($logo_size - $goods_name_size * 2);
        imagefttext($t_logo2, $goods_name_size, 0, $left, $left_top, $textcolor2, $font, mb_convert_encoding($text, 'html-entities', 'UTF-8'));*/

        // 长按识别小程序 跟团购买
        $text_x = 274;
        $text_y = 46;
        $left_top = $back_height - $text_y - 57;
        $mini_bg = imagecreatefromstring(file_get_contents($param['mini_bg']));
        $source_info = getimagesize($param['mini_bg']);
        imagecopyresampled($t_logo2, $mini_bg, $left, $left_top, 0, 0, $text_x, $text_y, $source_info[0], $source_info[1]);

        imagepng($t_logo2, $refer_qrcode_logo);
    }

    return $refer_qrcode_logo;
}

/**
 * 分行处理
 * @param $pos
 * @param $string
 * @param $line
 * @return array
 */
function draw_txt_to($pos, $string, $line = 2)
{
    $font = getFont();
    $_string = '';
    $__string = array();
    for ($i = 0; $i < mb_strlen($string, 'utf-8'); $i++) {
        $box = imagettfbbox($pos['fontsize'], 0, $font, $_string);
        $_string_length = $box[2] - $box[0];
        $box = imagettfbbox($pos['fontsize'], 0, $font, mb_substr($string, $i, 1, 'utf-8'));

        if ($_string_length + $box[2] - $box[0] < ($pos['width'] - $pos['left'])) {
            $_string .= mb_substr($string, $i, 1, 'utf-8');
        } else {
            if (count($__string) >= ($line - 1)) {
                $_string = mb_substr($_string, 0, mb_strlen($_string, 'utf-8') - 1, 'utf-8') . '...';
                break;
            }
            $pos['left'] = 0;
            $__string[] = $_string;
            $_string = mb_substr($string, $i, 1, 'utf-8');
        }
    }
    $__string[] = $_string;
    return $__string;
}

调用

activity_poster();

海报截图

总结

使用GD库函数,首先创建画布,然后根据画布大小定位加载其他内容。

不同效果可参考上方代码来调整实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ASP.NET Core 入门

使用 .NET CLI 创建并运行 ASP.NET Core Web 应用。 文章目录 一、先决条件二、创建Web应用项目三、运行应用四、编辑Razor页面 一、先决条件 .NET 8.0 SDK 二、创建Web应用项目 打开命令行界面&#xff0c;然后输入以下命令&#xff1a; dotnet new webapp --output aspne…

基于 Flask 和 Socket.IO 的 WebSocket 实时数据更新实现

简介 随着现代化应用的快速发展&#xff0c;实时数据交互已经成为许多 Web 应用的核心需求&#xff0c;比如实时消息推送、数据监控大屏等。本文将基于一个完整的 WebSocket 实现示例&#xff0c;带你一步步理解如何使用 Flask 和 Socket.IO 构建实时数据更新的 Web 应用。 将…

十、Spring Boot集成Spring Security之HTTP请求授权

文章目录 往期回顾&#xff1a;Spring Boot集成Spring Security专栏及各章节快捷入口前言一、HTTP请求授权工作原理二、HTTP请求授权配置1、添加用户权限2、配置ExceptionTranslationFilter自定义异常处理器3、HTTP请求授权配置 三、测试接口1、测试类2、测试 四、总结 往期回顾…

详细介绍HTTP与RPC:为什么有了HTTP,还需要RPC?

目录 一、HTTP 二、RPC 介绍 工作原理 核心功能 如何服务寻址 如何进行序列化和反序列化 如何网络传输 基于 TCP 协议的 RPC 调用 基于 HTTP 协议的 RPC 调用 实现方式 优点和缺点 使用场景 常见框架 示例 三、问题 问题一&#xff1a;是先有HTTP还是先有RPC&…

【Linux】 进程是什么

0. 什么是进程&#xff0c;为什么要有进程&#xff1f; 1.操作系统为了更好的管理我们的软硬件&#xff0c;抽象出了许多概念&#xff0c;其中比较有代表的就是进程了。通俗的来说操作系统为了更好的管理加载到内存的程序&#xff0c;故引入进程的概念。 2.在操作系统学科中用P…

[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker编译环境镜像下载以及使用方式

T. 已测试目录 主机类型主机版本Docker镜像版本结果WSL2Ubuntu22.04Ubuntu20.04PASSWSL2Ubuntu22.04Ubuntu18.04PASS R. 软硬件要求&#xff1a; 编译硬件需求&#xff1a;做多系统测试&#xff0c;磁盘500GB起步(固态)&#xff08;机械会卡死&#xff09;&#xff0c;内存3…

vue3-使用vite创建项目

vue-cli处于维护模式&#xff0c;也可以使用脚手架正常创建vue3项目&#xff0c;与vue2创建方式一致 官方推荐使用vite创建项目 vite 是新一代前端构建工具,官网地址轻量快速的热重载&#xff08;HMR&#xff09;&#xff0c;能实现极速的服务启动。对 TypeScript、JSX、CSS 等…

Java设计模式笔记(一)

Java设计模式笔记&#xff08;一&#xff09; &#xff08;23种设计模式由于篇幅较大分为两篇展示&#xff09; 一、设计模式介绍 1、设计模式的目的 让程序具有更好的&#xff1a; 代码重用性可读性可扩展性可靠性高内聚&#xff0c;低耦合 2、设计模式的七大原则 单一职…

Vue3+node.js实现登录

文章目录 前端代码实现后端代码实现跨域处理 前端代码实现 效果图 前端代码实现 <template><div class"login-container"><el-card class"login-card"><template #header><div class"card-header"><span>…

网络原理(一)—— http

什么是 http http 是一个应用层协议&#xff0c;全称为“超文本传输协议”。 http 自 1991 年诞生&#xff0c;目前已经发展为最主流使用的一种应用层协议。 HTTP 往往基于传输层的 TCP 协议实现的&#xff0c;例如 http1.0&#xff0c;http1.0&#xff0c;http2.0 http3 是…

Next.js-样式处理

#题引&#xff1a;我认为跟着官方文档学习不会走歪路 Next.js 支持多种为应用程序添加样式的方法&#xff0c;包括&#xff1a; CSS Modules&#xff1a;创建局部作用域的 CSS 类&#xff0c;避免命名冲突并提高可维护性。全局 CSS&#xff1a;使用简单&#xff0c;对于有传统…

navicat premium连接sqlserver

连接不上就双击安装图中的msi文件之后再连试试&#xff01;

Axure RP教程:创建高效用户界面和交互

Axure RP是一款广受好评的软件&#xff0c;专门用于设计精致的用户界面和交互体验。这款软件提供了众多UI控件&#xff0c;并根据它们的用途进行了分类。与此同时&#xff0c;国产的即时设计软件作为Axure的替代品&#xff0c;支持在线协作和直接在浏览器中使用&#xff0c;无需…

Qt导出Excel图表

目的 就是利用Qt导出Excel图表,如果直接画Excel 图表&#xff0c;比较麻烦些&#xff0c;代码写得也复杂了&#xff1b;而直接利用Excel模块就简单了&#xff0c;图表在模块当中已经是现成的了&#xff0c;Qt程序只更改数据就可以了&#xff0c;这篇文章就是记录一下利用模块上…

DeSTSeg: Segmentation Guided Denoising Student-Teacher for Anomaly Detection

DeSTSeg: Segmentation Guided Denoising Student-Teacher for Anomaly Detection 清华、苹果 个人感觉 Introduction 很自然的让读者理解作者问题的提出&#xff0c;也有例子直接证明了这个问题的存在&#xff0c;值得借鉴&#xff01;&#xff01; Related work写的也很不…

Java设计模式 —— 【创建型模式】工厂模式(简单工厂、工厂方法模式、抽象工厂)详解

文章目录 前言一、简单工厂&#xff08;静态工厂&#xff09;1、概述2、代码实现3、优缺点 二、工厂方法模式1、概述2、代码实现3、优缺点 三、抽象工厂模式1、概述2、代码实现3、优缺点 四、总结 前言 先看个案例&#xff1a;【手机和手机店】在没有工厂的时候&#xff0c;手…

利用Java爬虫获取阿里巴巴中国站跨境属性的详细指南

在全球化贸易的浪潮中&#xff0c;跨境电商正成为连接全球买家和卖家的重要桥梁。阿里巴巴中国站作为全球领先的B2B电子商务平台&#xff0c;提供了海量的商品信息&#xff0c;其中跨境属性信息对于跨境电商尤为重要。本文将详细介绍如何使用Java编写爬虫&#xff0c;从阿里巴巴…

「Qt Widget中文示例指南」如何为窗口实现流程布局?(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文将展示如何为不…

鸿蒙学习使用模拟器运行应用(开发篇)

文章目录 1、系统类型和运行环境要求2、创建模拟器3、启动和关闭模拟器4、安装应用程序包和上传文件QA:在Windows电脑上启动模拟器&#xff0c;提示未开启Hyper-V 1、系统类型和运行环境要求 Windows 10 企业版、专业版或教育版及以上&#xff0c;且操作系统版本不低于10.0.18…

Java后端如何进行文件上传和下载 —— 本地版

简介&#xff1a; 本文详细介绍了在Java后端进行文件上传和下载的实现方法&#xff0c;包括文件上传保存到本地的完整流程、文件下载的代码实现&#xff0c;以及如何处理文件预览、下载大小限制和运行失败的问题&#xff0c;并提供了完整的代码示例。 大体思路 1、文件上传 …