PHP使用Grafika合成图片,生成海报图

article/2025/8/22 1:09:02

需求背景:
在小程序上生成海报图,但在保存图片时,只能保存其中的小程序码图片,保存下来的图片过于单调,且无法确认该图片的作用性,所以需要调整为保存一整张海报图。

海报效果图:
在这里插入图片描述

需求分析:
在海报图中,背景图、头像、文字、还有小程序码都是各自独立的部分,我们需要把这些图片合并起来,然后输出为一整张图片,这样就可以直接长按保存图片了。

合并图片可以用以下方法:

  1. 在前端合成,使用画布canvas,把各个元素“画”进去;
  2. 在后端合成,使用插件Grafika,把各个组成部分合并在一起;

因为当前是在小程序开发这个需求,考虑到未来可能会替换海报上的一些文字、图片等情况,而每次修改小程序代码都需要提交版本审核,耗时耗力,所以决定在后端进行图片合成,输出图片到前端。

注意:若背景图片有透明的部分,处理过后,透明部分会变成黑色,在Grafika中暂未找到能合并透明图片的方法,感觉有点坑,不过有搜到说可以直接用gd来合成,有空再研究研究吧。(目前的解决方法是换张白色背景的图片)

使用Grafika

安装:

composer require kosinix/grafika:dev-master --prefer-dist

生成方法

function create($slogan, $avatar, $qr){// 背景图片$bg_img = 'images/qr_code_bg.png';// 实例化图像编辑器$editor = Grafika::createEditor(['Gd']);// 打开海报背景图$editor->open($backdropImage, $bg_img);$bgWidth = $backdropImage->getWidth();// 生成圆形用户头像$avatarUrlName = 'temp/avatar.png';$this->circular($avatar_url, $avatarUrlName);// 打开用户头像$editor->open($avatarImage, $avatarUrlName);// 重设用户头像宽高$avatarWidth = 310;$editor->resizeExact($avatarImage, $avatarWidth, $avatarWidth);// 用户头像添加到背景图$avatarX = 401;$avatarY = 36;$editor->blend($backdropImage, $avatarImage, 'normal', 1.0, 'top-left', $avatarX, $avatarY);// 打开小程序码$editor->open($qrcodeImage, $qr);// 重设小程序码宽高$qrcodeWidth = 430;$editor->resizeExact($qrcodeImage, $qrcodeWidth, $qrcodeWidth);// 小程序码添加到背景图$qrcodeX = 340;$qrcodeY = 720;$editor->blend($backdropImage, $qrcodeImage, 'normal', 1.0, 'top-left', $qrcodeX, $qrcodeY);// 处理文字$color = new Color('#FFFFFF');$fontPath = Grafika::fontsDir() . '/st-heiti-light.ttc';$fontSize = 50;// 处理用户昵称$nicknameBox = $this->get_text_box($nickname, $fontSize, $fontPath);$fontY = 410;$fontX = ($bgWidth / 2) - ($nicknameBox[0] / 2);$editor->text($backdropImage, $nickname, $fontSize, $fontX, $fontY, $color, $fontPath);$str1 = "邀请您注册成为分销员";$strBox1 = $this->get_text_box($str1, $fontSize, $fontPath);$str1x = ($bgWidth / 2) - ($strBox1[0] / 2);$editor->text($backdropImage, "邀请您注册成为分销员", $fontSize, $str1x, $fontY + 100, $color, $fontPath);$str2 = "一起赚佣金";$strBox2 = $this->get_text_box($str2, $fontSize, $fontPath);$str2x = ($bgWidth / 2) - ($strBox2[0] / 2);$editor->text($backdropImage,'一起赚佣金', $fontSize, $str2x, 1220, $color, $fontPath);// 保存图片$editor->save($backdropImage, $qr);
}
  • 使用open()打开图片并获得该图片对象,使用blend()依次合并图片。
  • 在处理头像图片时,需要先指定临时的头像文件,便于后续使用。
  • 添加文字到图片上时text(),Grafika默认的字体不兼容中文,所以需要指定字体文件路径。
// 生成圆形用户头像
function circular($imgpath, $saveName = ''){$ext = pathinfo($imgpath);$srcImg = null;switch ($ext['extension']) {case 'jpg':case 'jpeg':$srcImg = imagecreatefromjpeg($imgpath);break;case 'png':$srcImg = imagecreatefrompng($imgpath);break;}// 获取图片尺寸$w = imagesx($srcImg);$h = imagesy($srcImg);// 设定图片宽高(正方形)$w = $h = min($w, $h);$newImg = imagecreatetruecolor($w, $h);// 必须imagesavealpha($newImg, true);// 拾取一个完全透明的颜色,最后一个参数127为全透明$bg = imagecolorallocatealpha($newImg, 255, 255, 255, 127);imagefill($newImg, 0, 0, $bg);$r = $w / 2; //圆半径for ($x = 0; $x < $w; $x++) {for ($y = 0; $y < $h; $y++) {$rgbColor = imagecolorat($srcImg, $x, $y);if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {imagesetpixel($newImg, $x, $y, $rgbColor);}}}// 输出图片到文件imagepng($newImg, $saveName);// 释放空间imagedestroy($srcImg);imagedestroy($newImg);
}
  • 方法的大概思路是:创建一个正方形的透明图片,通过循环,把透明图片上的圆形部分的像素点画上(替换)头像图片对应的像素点,此时得到的图片就是一个圆形的头像图片。
  • 方法中使用了imagecreatetruecolor(),创建真彩图像。此时需要保证使用的图片位数>24(图片文件>属性>详细信息>位深度),否则无法渲染图像成功,结果得到的图片是黑色的。
  • 除了使用php内置函数实现圆形图片外,还可以安装Imagick扩展,更方便。
// 获取字符串宽高
function get_text_box($text, $size, $font){$point = imagettfbbox($size, 0, $font, $text);$width = $point[4] - $point[6];$height = $point[1] - $point[7];return [$width, $height];
}
  • 使用imagettfbbox()来获取字符串所在的坐标轴,从而可以拿到字符串文本框的宽高,把字符串居中合并到背景图上。

因为目前无法生成用于前端展示的透明背景的图片,所以改成前端展示的还是一个弹窗,弹窗上添加一个长按事件,触发下载合成海报图片到用户相册

// 长按点击事件
downloadQrCode(){wx.showLoading({title: "加载中",mask: true});if(this.data.download_qr_code){this.downloadSaveImage(this.data.download_qr_code);}else{        App._get("user/download_agent_qr_code", {}, (result) => {if(!result.res){wx.showToast({ icon: 'none', title: result.msg });return false;}this.setData({download_qr_code: result.data.url});this.downloadSaveImage(result.data.url);}, null, (res) => {wx.hideLoading();});}
},
/*** 下载图片,并保存到用户相册* @param {string} url 图片地址*/
downloadSaveImage(url){wx.getImageInfo({src: url,success: function (ret) {var path = ret.path;wx.saveImageToPhotosAlbum({filePath: path,success(result) {wx.hideLoading();wx.showToast({ icon: 'none', title: "已保存图片到相册" });},fail(result) {wx.hideLoading();if(result.errMsg.indexOf("saveImageToPhotosAlbum:fail auth deny") !== -1){wx.showToast({ icon: 'none', title: "请允许小程序“保存图片到相册”" });}console.log(result)}});},fail: function(result){wx.hideLoading();console.log(result)}});
},
  • App._get() 为发送get请求公共方法

参考:
Grafika官方文档
PHP 将图片切成圆角


http://chatgpt.dhexx.cn/article/Y2UL7mfd.shtml

相关文章

合成海报的小程序插件-票圈海报

概述 票圈海报 是一个用于生成海报的小程序插件&#xff0c;通过灵活简单的配置(JSON)就可以生成精美的分享海报&#xff0c;适用于小程序的朋友圈分享等营销裂变场景。 可以绘制文字、图片、线条、色块到海报画布&#xff0c;支持设置宽高、透明度、层级甚至圆角等属性。 亮…

PHP 海报二维码合成

组合参数方法&#xff1a; /*** [user_qrcode 参数组合]* param [type] $bgImg [背景图]* param [type] $codeImg [二维码]* param string $name [名称]* param string $remask [备注]* param string $content [描述]* param integer $key [生成二维码名称…

vue两张图片合成一张(海报二维码合成工具)

公司要经常换海报&#xff0c;一个海报要不同的二维码&#xff0c;做一个工具解决一下。 效果图如下 二维码图片的位置和海报大小可以随意调整 直接放代码&#xff1a; <template><div class"all-tool"><div :style"bgStyle" class"…

【Web技术】961- 3分钟搞定海报合成

背景 在推广业务中&#xff0c;常常会遇到合成带二维码海报分享功能&#xff0c;并且为了推广力度&#xff0c;需要同时在APP、WEB、小程序都有此功能加大曝光&#xff0c;各端都需要单独编写&#xff0c;复用能力差&#xff0c;效率低。本身合成海报业务并无难度&#xff0c;在…

如何合成动态海报?手把手教你一键在线合成gif海报

相信大家在平时都见过那种gif动态海报图片吧&#xff01;是不是觉得只有专业的设计师才能制作呢&#xff1f;其实&#xff0c;这种gif动态海报制作起来非常的简单&#xff0c;只需要准备几张图片尺寸相同图文内容不同的图片&#xff0c;再使用**在线动画制作**工具&#xff0c;…

波束形成MATLAB代码

常规的波束形成方法 clc; clear; close all;fs 1000; c 150; N 128; f 100; lambda c / f; d 0.5 * lambda; theta 1: 1: 180; t (0:1:1000-1) / fs;A zeros(1, length(theta)); A(5) 5; A(20) 4; A(25) 5; A(50) 3; % 在这四个方向上有目标 S zeros(length(th…

相移波束形成算法的MATLAB仿真

仿真结果如下&#xff1a; 部分核心程序如下所示&#xff1a; %************************************************************************** % 相移波束形成算法 %************************************************************************** %…

【波束形成】MMSE波束形成,自适应MMSE波束形成以及自适应MBER波束形成

1.软件版本 matlab2013b 2.本算法理论知识 3.部分源码 clc; clear; close all; warning off;SNR_set [0:1:12]; BER 1; nRx 10; nTx 10; frame_length 1000; Bers []; %论文table 2 alpha [0,10,-15,30,-45,50,60,-5…

基于FPGA的波束形成verilog开发

目录 一、理论基础 二、核心程序 三、仿真测试结果 一、理论基础 根据原理可知&#xff0c;整个波束形成的基本结构框图如下图所示&#xff1a; 这里&#xff0c;我们使用的加权函数为&#xff1a; 这个模块&#xff0c;相当于上述结构的&#xff1a; 二、核心程序 timesca…

鲁棒自适应波束形成

鲁棒自适应波束形成 本文是我关于Microphone Arrays Signal Processing Techniques and Applications第五章的整理。 自适应形成其方向性的波束形成器称为自适应波束形成器。它同时进行波束控制和零位控制。然而&#xff0c;在大多数声波束形成器中&#xff0c;只有在目标DOA是…

窄带波束形成——时域与频域常规窄带波束形成

最近学习了一下《最优阵列处理技术》&#xff0c;应老师要求写一个线性均匀水听器阵列的常规波束形成&#xff0c;由于是初学者&#xff0c;写的可能会有点问题&#xff0c;欢迎大家提出修改建议和指导&#xff0c;写这个主要是记录自己的思考&#xff0c;其次是和初学者进行交…

麦克风阵列波束形成

原文转载于&#xff1a;http://blog.csdn.net/shichaog/article/details/74143427 有所修改 感谢作者 波束形成 beamforming 体现的是声源信号的空域选择性&#xff0c;许多传统波束形成方法具有线性处理结构&#xff1b; 波束形成需要考虑三个方面&#xff1a; 1.麦克风…

LMS波束形成

LMS自适应波束形成器 % 标量阵最小均方准则(LMS)自适应波束形成器(ADBF) close all; Sound_velocity1200; %声速 Frequency300; %信号频率 Sample_Frequency100Frequency; %采样频率 Array_num16; %阵元数 Array_distance1/2(Sound_velocity/Frequency); %阵元间距 Signal_Leng…

波束形成(最大信噪比准则、LCMV、MSC、LMS、RLS)

波束形成&#xff08;最大信噪比准则、LCMV、MSC、LMS、RLS&#xff09; 波束形成的基本概念 # 波束形成准则 分别对上面所阐述的最大信噪比准则&#xff0c;旁瓣对消器&#xff0c;线性最小均方误差&#xff0c;以及自适应LMS和RLS算法进行仿真。 最大信噪比准则&…

语音领域的波束形成Beamforming小结

关注、点赞、收藏是对我最大的支持&#xff0c;谢谢^v^ 目录 1. 背景介绍 2. 多通道信号的公式描述 3. 传统波束形成&#xff08;delay-and-sum和filter-and-sum&#xff09; 4. MVDR 4.1 传统MVDR 4.2 融入深度学习的MVDR 5. GEV(Generalized eigenvalue) beamformer …

空间谱专题02:波束形成(Beamforming)

作者&#xff1a;桂。 时间&#xff1a;2017-08-22 10:56:45 链接&#xff1a;http://www.cnblogs.com/xingshansi/p/7410846.html 前言 本文主要记录常见的波束形成问题&#xff0c;可以说空间谱估计是波束形成基础上发展而来&#xff0c;在系统论述空间谱之前&#xff0c;有…

UE4 插件 简单全景播放器

UE4 插件 1分钟完成全景展示项目&#xff08;Simple panorama player and video player&#xff09; 全景图、全景视频播放器&#xff0c;附带列表和热点模板。另附带一个视频播放器。全景播放器可以使用本地资源或Web URL。 完全由蓝图实现&#xff0c;易于扩展和修改。 具有…

Android VR Player(全景视频播放器) [10]: VR全景视频渲染播放的实现(exoplayer,glsurfaceview,opengl es)

前言 此博客的大部分内容来自我的毕业设计论文&#xff0c;因此语言上会偏正式一点&#xff0c;如果您有任何问题或建议&#xff0c;欢迎留言。在此感谢实验室的聂师兄&#xff0c;全景视频render部分的代码设计主要参考了他所编写的代码来完成&#xff0c;他对视频渲染过程的…

VR+全景播放器+头控讲解-07

VR全景播放器头控讲解-01-知识储备VR全景播放器头控讲解-02-创建球体VR全景播放器头控讲解-03-渲染视频VR全景播放器头控讲解-04-滑动手势VR全景播放器头控讲解-05-伸缩画面VR全景播放器头控讲解-06-头控实现VR全景播放器头控讲解-07-分屏技术 学习目标 如何实现分屏 实现思路 …

[OpenGL]从零开始写一个Android平台下的全景视频播放器——目录

Github项目地址 为了方便没有准备好梯子的同学&#xff0c;我把项目在CSDN上打包下载&#xff0c;不过不会继续更新&#xff08;保留在初始版本&#xff09; 先放一张效果图&#xff1a; Youtube 优酷 前言 Android平台下的全景视频&#xff08;360&#xff0c;Panoram…