当前位置: 首页 > news >正文

千里共婵娟 | 结合微信公众号用JavaScript完整开发实现换中秋头像的功能

在这里插入图片描述

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,阿里云社区专家博主,2023年6月csdn上海赛道top4。
🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。
🏆本文已收录于专栏:100个JavaScript的小应用,微信公众号开发。
🎉欢迎 👍点赞✍评论⭐收藏

文章目录

  • 🚀一、前言
  • 🚀二、开发流程概述
  • 🚀三、配置微信公众号
    • 🔎3.1 AppId和AppSecret获取
    • 🔎3.1 添加网页授权域名
    • 🔎3.3 白名单设置
  • 🚀四、功能开发
    • 🔎4.1 获取用户微信头像
      • 🍁4.1.1 引导用户进入授权页面
      • 🍁4.1.2 获取授权code并换取access_token
      • 🍁4.1.3 获取用户基本信息
    • 🔎4.2 JavaScript实现用户换头像
      • 🍁4.2.1 创建HTML结构(index.php)
      • 🍁4.2.2 拼接头像和相框
      • 🍁4.2.3 生成头像为一个图片
  • 🚀五、总结


🚀一、前言

中秋节是我国的重要传统节日,今年直接和国庆节凑到了一起,放一个8天的小长假,是不是很兴奋呢。为了增加节日气氛,许多人会更换自己的社交媒体头像,如微信头像。使用与中秋或者国庆主题相关的图片。本篇博文将介绍如何使用PHP通过微信公众号获取用户头像,并且将头像传递给JavaScript开发一个实现换中秋头像的功能。

在这里插入图片描述

通过本篇文章的阅读,您将获取如下的实战知识:

  1. 熟悉了解微信公众号的基本开发流程。
  2. 学习到微信公众号网页授权获取用户基本信息这个板块的开发。
  3. 基本掌握html,css等网页前端的组成与基本开发流程。
  4. Javascript, canvas用于图片合成,头像生成的场景使用。
  5. 学习到一部分PHP相关的后端知识

🚀二、开发流程概述

首先我们得通过微信公众号开发获取到用户的头像,然后我们需要准备一些素材。这个图片素材需要是镂空图 PNG,用来镶嵌在用的真实头像上面。接下来,我们需要创建一个HTML页面,并在其中引入一个JavaScript文件。我们将使用JavaScript来操作DOM元素和Canvas元素,实现换装功能。如果您熟悉HTMLJavaScript的基本知识那就更好了。

🚀三、配置微信公众号

🔎3.1 AppId和AppSecret获取

AppIdAppSecret得先获取到,请看下图,记得一定要保存好AppSecret
在这里插入图片描述

🔎3.1 添加网页授权域名

网页授权域名是必须要添加的,否则公众号是不回允许在没有通过的域名下面进行授权。如果你遇到了一些问题,可以排查一下是不是这个地方的配置。在公众号设置>功能设置里面添加,加域名就行。

在这里插入图片描述

这里可能要传文件验证,如果传了文件还是有问题,可以检查一下文件权限啥的,或者看看能不能手动访问。

🔎3.3 白名单设置

白名单主要是添加自己服务器所在的IP地址到公众号后台,这样只有指定的服务器才允许与公众号接口通信。如果白名单没有设置,获取access_token的时候可能会报如下错误。

{"errcode":40164,"errmsg":"invalid ip xxx ipv6 ::ffff:xxxx, not in whitelist rid: 6503251e-14033bf0-774d3d3e"}

在这里插入图片描述

在安全中心>IP白名单处进行设置,白名单设置了可能会有短暂的延时生效,如果当时不能访问,可以等会再试一下。

🚀四、功能开发

🔎4.1 获取用户微信头像

这个部分主要通过PHP进行开发,核心是如何与公众号进行API交互。

🍁4.1.1 引导用户进入授权页面

构建一个URL,用户点击后将跳转到微信授权页面,同时携带着您设置的回调URL。

$redirect_uri = urlencode('http://your-domain.com/callback.php'); // 回调URL,需要urlencode
$appid = 'Your Appid'; // 公众号AppID
$scope = 'snsapi_userinfo'; // snsapi_base或snsapi_userinfo
$state = 'STATE'; // 自定义参数,可不填
$auth_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appid}&redirect_uri={$redirect_uri}&response_type=code&scope={$scope}&state={$state}#wechat_redirect";
header('Location: ' . $auth_url); // 跳转到授权页面

在到达callback.php之前,如果已经关注了公众号的用户,可以直接获取到用户头像,否则则会提示授权,用户同意之后才能获取头像,这便是网页授权获取用户头像的核心功能。授权的情况可以见下图真实案例。

在这里插入图片描述

🍁4.1.2 获取授权code并换取access_token

用户同意授权后,微信会重定向到您设置的回调URL,并携带一个code参数。在回调页面(callback.php)中获取到该code,并使用它来换取access_tokenopenid

$code = $_GET["code"]; // 授权code
$appid = 'Your Appid'; // 公众号AppID
$secret = 'Your App Secret'; // 公众号App Secret// 通过code换取access_token
$token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$secret}&code={$code}&grant_type=authorization_code";
$token_data = json_decode(file_get_contents($token_url), true);$access_token = $token_data['access_token']; // 获取到的access_token
$openid = $token_data['openid']; // 用户的openid

🍁4.1.3 获取用户基本信息

使用获取到的access_tokenopenid,可以调用以下API来获取用户基本信息:

$userinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$openid}&lang=zh_CN";
$userinfo_data = json_decode(file_get_contents($userinfo_url), true);$nickname = $userinfo_data['nickname']; // 用户昵称
$headimgurl = $userinfo_data['headimgurl']; // 用户头像链接
// 可以根据需要获取其他用户信息字段
header('Location: https://www.xxx.wang/index.html?avatar_url=' . $headimgurl

上面代码的最后一句是重点,将获取到的微信头像传递给index.html,后面javascript会用到。

🔎4.2 JavaScript实现用户换头像

🍁4.2.1 创建HTML结构(index.php)

在HTML文件中,我们可以使用<input type="file">元素来让用户选择要上传的头像文件。同时,我们还需要一个<canvas></canvas>元素来绘制新的头像。

<!DOCTYPE html>
<html>
<head><title>头像换装</title>
</head>
<body><h1>头像换装</h1><div id="avatar"><img src="./img/head0.png" alt="0" id="avatar_template" style="z-index: 1000;pointer-events: none;"><img src="" alt="" id="avatar_img" class="pinch-zoom"></div><p class="hide"><canvas style="width:500px;height:500px;" id="cvs"></canvas></p><div style="display: none;" class="avatar-final"><div class="finished-img"><img id="finishedImg" src=""/><br></div><p class="control"><a class="css_btn_create" id="download">生成</a></p></div><script src="main.js"></script><script>loadImage()</script>
</body>
</html>

这里我用photoshop制作这么一个相框图片,里面加载头像,就是上面的head0.png

在这里插入图片描述

🍁4.2.2 拼接头像和相框

其中avatar_template就是我们的头像相框,avatar_img就是我们的微信头像,通过下面的方式来讲头像放到img标签里面。并且将拼接好的图片放到finishedImg里面。

// 将url的图片加载到页面
function loadImage() {let imgUrl = getQueryString('avatar_url');// 通过路径解析处高清图像imgUrl = headImgHD(imgUrl);$('#avatar_img').attr('src', imgUrl);$('#avatar_img').attr('crossOrigin', 'anonymous');curImage = $('#avatar_template').attr('src');drawToCanvas(imgUrl, curImage, $('#finishedImg'));
}// 开始整合绘制图片到finishedImg里面
function drawToCanvas(img1, img2, showObj) {let cvs = document.getElementById('cvs');let showSize = 230;let size = 800;cvs.width = size;cvs.height = size;let ctx = cvs.getContext('2d');let image1 = new Image;image1.setAttribute('crossOrigin', 'anonymous');image1.src = img1;image1.onload = function () {let width = image1.width < image1.height ? size : size * (image1.width / image1.height);let height = image1.width > image1.height ? size : size * (image1.height / image1.width);let x = image1.width < image1.height ? 0 : (size * (image1.width / image1.height) - size) / 2;let y = image1.width > image1.height ? 0 : (size * (image1.height / image1.width) - size) / 2;document.getElementById('avatar_img').style.showSize = width + 'px';document.getElementById('avatar_img').style.showSize = height + 'px';document.getElementById('avatar_img').style.marginLeft = -x + 'px';document.getElementById('avatar_img').style.marginTop = -y + 'px';ctx.drawImage(image1, -x, -y, width, height);let image2 = new Image;image2.setAttribute('crossOrigin', 'anonymous');image2.src = img2;image2.onload = function () {ctx.drawImage(image2, 0, 0, size, size);let canvas = document.getElementById('cvs');//获取二维码中的图片地址let src_xp = canvas.toDataURL('image/jpeg');$(showObj).attr('src', src_xp)}}
}

🍁4.2.3 生成头像为一个图片

当用户完成头像换装后,我们可以提供一个按钮来让用户生成新的头像。这里,我们可以使用html2canvas方法将页面元素转化为一个整体的图片,并将其显示在页面中。这个时候我们可以长按图片保存,然后上传到我的头像就完成了换头像的功能。

$('#download').click(function (ev) {takeScreenShot();
});function takeScreenShot() {html2canvas(document.getElementById('avatar'), {allowTaint:false,dpi: 400,useCORS: true,onrendered: function(canvas) {document.body.appendChild(canvas);var canvas = $('canvas')[1];//获取二维码中的图片地址let src_xp = canvas.toDataURL('image/jpeg');console.log(src_xp);$('#finishedImg').attr('src', src_xp)$('.avatar-final').show();$('#avatar-control').hide();$(canvas).hide();},});
}

最后,一起来看看最终的头像效果。

在这里插入图片描述

🚀五、总结

本篇博文介绍了如何使用JavaScript开发一个实现换中秋头像功能的应用程序。我们通过与微信公众号头像打通,并使用Html进行页面绘制。最后,通过Canvas进行图片整合,并提供一个生成按钮让用户一键生成新的头像。

在这里插入图片描述

如果你想直接体验换头像的功能,可以关注下面公众号回复【换头像】。今天的内容就到这里,我们下次见。

相关文章:

千里共婵娟 | 结合微信公众号用JavaScript完整开发实现换中秋头像的功能

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…...

pt26django教程

admin 后台数据库管理 django 提供了比较完善的后台管理数据库的接口&#xff0c;可供开发过程中调用和测试使用 django 会搜集所有已注册的模型类&#xff0c;为这些模型类提拱数据管理界面&#xff0c;供开发者使用 创建后台管理帐号: [rootvm mysite2]# python3 manage.…...

javabasic

计算机基础 一、学前知识 1. 计算机组成 2. 进制的概念 &#xff08;1&#xff09;二进制的存储 计算机不管是内存还是硬盘&#xff0c;都是以二进制的形式存储。如同一张巨大的表格&#xff0c;里面都是由0和1组成。 二进制&#xff1a;逢2进1 基数为2&#xff0c;数值部分…...

电子词典项目

目录 目录 头文件&#xff1a;dict.h: 源文件&#xff1a;dict.c: 服务器测试文件&#xff1a;serDict.c: 客户端测试文件&#xff1a;cliDict.c: 头文件&#xff1a;dict.h: #ifndef __DICT_H__ #define __DICT_H__ #include<myhead.h> #include<sqlite3.h>#de…...

SQL12 高级操作符练习(2)

描述 题目&#xff1a;现在运营想要找到学校为北大或GPA在3.7以上(不包括3.7)的用户进行调研&#xff0c;请你取出相关数据&#xff08;使用OR实现&#xff09; 示例&#xff1a;user_profile iddevice_idgenderageuniversitygpa12138male21北京大学3.423214male复旦大学4.03…...

python写代码过程中的坑230915

1.解释代码IndentationError: expected an indented block 这个错误通常是由于代码缩进错误导致的。 在Python中,代码块(如循环、条件语句、函数等)通常使用缩进来表示。因此,如果你在期望缩进的位置没有正确缩进代码,就会出现"IndentationError: expected an inden…...

SpringBoot课堂笔记20230913

本篇文章为SpringBoot学习笔记&#xff0c;方便自己再复习。 Maven&#xff1a;jar包管理工具 注解&#xff1a; Controller:处理http请求&#xff0c;返回的视图 RestController: 相当于ResponseBody和Controller一起用&#xff0c;返回的是json ResponseBody:返回响应内容 …...

3D数字孪生:从3D数据采集到3D内容分析

数字孪生&#xff08;Digital Twin&#xff09;是物理对象、流程或系统的虚拟复制品&#xff0c;用于监控、分析和优化现实世界的对应物。 这些数字孪生在制造、工程和城市规划等领域变得越来越重要&#xff0c;因为它们使我们能够在现实世界中实施改变之前模拟和测试不同的场景…...

【杂记】git管理工具的相关应用

这里记录一些用git管理工具进行开发的命令&#xff0c;便于自己查看&#xff0c;我认为下面两篇博客写的很详细&#xff0c;但是为了自己方便查看&#xff0c;所以自己写了一些命令供自己进一步理解。gitee相对git来说更方便一些&#xff08;毕竟国内的不用担心墙&#xff09;&…...

看好多人都在劝退学计算机,可是张雪峰又 推荐过计算机,所以计算机到底是什么样 的?

张雪峰高考四百多分&#xff0c;但是他现在就瞧不起400多分的学生。说难听点&#xff0c;六七百分的 热门专业随便报谁不会啊&#xff1f; 计算机专业全世界都是过剩的&#xff0c;今年桂林电子科技&#xff0c;以前还是华为的校招大学&#xff0c;今年 计算机2/3待业。这个世…...

leetcode 26.删除有序数组中的重复项

给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c;你需要做…...

jitsi音视频会议集成到自己的网页中

将jitsi视频会议集成到自己的web网站&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html lang"en" xmlns:th"http://www.thymeleaf.org"> <head><meta charset"UTF-8"><meta name"viewport" content&…...

浅析Java责任链模式实现

一、概要 定义&#xff1a;责任链模式是一种行为设计模式&#xff0c; 允许你将请求沿着处理者链进行发送。收到请求后&#xff0c; 每个处理者均可对请求进行处理&#xff0c; 或将其传递给链上的下个处理者。 二、应用场景&#xff1a; 1.多条件流程判断&#xff1a;权限相关…...

SpringBoot雪花算法主键ID传到前端后精度丢失问题的解决

Java后端Long类型的范围 -263~263&#xff0c;即&#xff1a;-9223372036854775808~9223372036854775807&#xff0c;它是19位的。 这个数字可以通过方法获得&#xff1a;Long.MAX_VALUE、Long_MIN_VALUE。 前端JS的数字类型的范围 -253~253&#xff0c;即&#xff1a;-9007…...

vue使用elementUI的upload上传文件封装

这篇文章的目的 将文件上传的方法封装一下&#xff0c;供大家统一调用, 话不多说&#xff0c;直接上代码 upload 核心参数说明 action 上传的地址accept 接受上传的文件类型multiple 是否开启多文件上传模式limit 限制上传个数fileList 文件列表disabled 是否禁用 upload 核心方…...

cenos自动启动tomcat

首先创建一个脚本 关闭tomcat 等待2分钟 启动tomcat 并且把日志输出在 /usr/local/tomcat/tomcatchognqi.log #!/bin/bashexport JAVA_HOME/usr/local/jdk/jdk1.8.0_211 export JRE_HOME$JAVA_HOME/jre# 日志文件路径和文件名 LOG_FILE"/usr/local/tomcat/tomcatchognqi.…...

OSI模型与数据的封装

1、OSI模型 上层|| 七层模型 四层模型|| 应用层| 表示层 应用层 http/ftp/ssh/ftps| 会话层 -----------------------------------------------------------------------| 传输层 传输层 tcp/udp ------------------------------…...

【李沐深度学习笔记】数据操作

本课观看地址 数据操作p1 N维数组样例 N维数组是机器学习和神经网络的主要数据结构 1-d向量就是样本的各特征抽象成一个向量&#xff1b;2-d矩阵的每一行是一个样本&#xff0c;每一行都是一个样本的特征向量 3-d可以表示RGB图片&#xff0c;RGB图像是一个三维数组&#xff…...

【蓝桥杯选拔赛真题61】Scratch小猫照镜子 少儿编程scratch图形化编程 蓝桥杯选拔赛真题解析

目录 scratch小猫照镜子 一、题目要求 编程实现 二、案例分析 1、角色分析...

vue3将页面导出成PDF文件(完美解决图片、表格内容分割问题)

vue3将页面导出成PDF文件&#xff08;完美解决图片、表格内容分割问题&#xff09; 1、安装依赖2、在utils中创建htmlToPDF.js文件3、在vue中引入并使用 1、安装依赖 npm install --save html2canvas // 页面转图片 npm install jspdf --save // 图片转pdf2、在utils中创建h…...

软件测试:黑盒测试用例的四种设计方法

一、输入域测试用例设计方法 输入域测试法是一种综合考虑了等价类划分、边界值分析等方法的综合方法&#xff0c;针对输入域测试法中可能出现的各种情况&#xff0c;输入域测试法主要考虑三个方面&#xff1a;  (1)极端测试(ExtremalTesting)&#xff0c;要求在输入域中选择测…...

数据库开发-MySQL基础DQL和多表设计

1. 数据库操作-DQL DQL英文全称是Data Query Language(数据查询语言)&#xff0c;用来查询数据库表中的记录。 1.1 介绍 查询关键字&#xff1a;SELECT 查询操作是所有SQL语句当中最为常见&#xff0c;也是最为重要的操作。在一个正常的业务系统中&#xff0c;查询操作的使…...

PowerDesigner 逆向工程以及IDEA中UML插件

1、MySQL数据库连接&#xff08;JDBC方式&#xff09; 1.1 新建一个pdm&#xff0c;dbms选择mysql 1.2 Database - Connect 选择数据库连接 1.3 配置连接信息 数据库连接这里是通过一个配置文件来获取连接信息的&#xff0c;首次的话因为没有&#xff0c;所以我们需要选择…...

企业架构LNMP学习笔记56

MongoDB数据类型操作&#xff1a;CURD 1、添加数据&#xff1a; mongodb里存储数据的格式文档形式&#xff0c;以bson格式的文档形式。 创建数据库&#xff1a; > use tp5shop switched to db tp5shop > db.getName() tp5shop使用切换库&#xff0c;不存在自动创建&am…...

[Linux入门]---搭建Linux环境

1.Linux环境的搭建方式 使用Linux操作系统的三种途径&#xff1a; 1.直接安装在物理机上&#xff0c;但是由于 Linux 桌面使用起来非常不友好&#xff0c;不推荐。 2.使用虚拟机软件&#xff0c;将 Linux 搭建在虚拟机上&#xff0c;但是由于当前的虚拟机软件(如 VMWare 之类的…...

性能测试知多少---性能分析与调优的原理

最近一直纠结性能分析与调优如何下手&#xff0c;先从硬件开始&#xff0c;还是先从代码或数据库。从操作系统&#xff08;CPU调度&#xff0c;内存管理&#xff0c;进程调度&#xff0c;磁盘I/O&#xff09;、网络、协议&#xff08;HTTP&#xff0c; TCP/IP &#xff09;&…...

“对象创建”模式

通过“对象创建”模式绕开new&#xff0c;来避免对象创建 (new) 过程中所导致的紧耦合(依赖具体类)从而支持对象创建的稳定。它是接口抽象之后的第一步工作。 典型模式 Factory MethodAbstract FactoryPrototypeBuilder Factory Method 动机 (Motivation) 在软件系统中&am…...

ipad手写笔有必要买吗?好用的平板触控笔

众所周知&#xff0c;随着Apple pencil的出现&#xff0c;市面上出现越来越多平替电容笔的出现&#xff0c;无论是价格和功能&#xff0c;几乎都很接近。很多小伙伴不知如何下手&#xff0c;不知道如何从众多品牌中挑选出适合自己的电容笔&#xff0c;今天我为大家总结一下网上…...

OpenGL ES视频特效开发参考Shadertoy参数详解参考Godot文档

今天一个大厂的学员过来问shadertoy上一些参数的问题&#xff0c;因为我之前用过一段时间Godot引擎&#xff0c; 我清晰记得Godot官方文档有明确的解释&#xff0c;所以整理下发给做特效的同学。 Shadertoy是一个网站&#xff0c;它方便用户编写片段着色器并创造出纯粹的魔法。…...

java:逆序排序的三种方法

// 逆序第一种方法 public static void main(String[] args) {int arr[] {11, 22, 33, 44, 55, 66};for (int i arr.length-1; i > 0; i--) {System.out.print("\t"arr[i]);}}缺点&#xff1a;这个是直接逆转&#xff0c;如果里面是随机数没办法比较 逆序第二种…...

北京高端别墅设计公司/东莞整站优化排名

GraphMat: High performance graph analytics made productive GraphMat&#xff1a;高性能图分析提高生产力 [Paper] [Slides] [Code] VLDB’15 摘要 弥合用户友好的图分析框架和本地手动优化代码之间的差距 采用结点编程(前端)并将其映射到后端的高性能稀疏矩阵运算, 性能…...

济南企业网站制作费用/网站排名系统

正文 在angular 2中&#xff0c;回调函数的返回结果&#xff0c;不会自动更新视图层的显示&#xff0c;可以用 ChangeDetectorRef 来驱动angular更新视图。 // 导入 import { Component, OnInit, Input, ChangeDetectorRef } from angular/core; // 注入 constructor(private…...

不能制作网页的软件有哪些/windows优化大师是哪个公司的

我想在这里做些奇怪的事情。我需要从一个守护进程启动一个logcat进程&#xff0c;该守护进程将在后台运行并打印到终端&#xff0c;而无需控制stdin。它是用于记录日志的&#xff0c;因此理想情况下logcat将打印日志消息&#xff0c;同时仍允许用户输入标准命令并从Shell初始化…...

永安网站建设/百度移动点击排名软件

python 文件太多打不开文件夹&#xff0c;取样少量的文件&#xff0c; 建立同样的文件目录结构 python 文件太多打不开文件夹&#xff0c;取样少量的文件 - 无左无右 - 博客园 import os import shutil import randomroot_file "/media/algo/data_1/everyday/20230203-有…...

wordpress 机器学习/阿里域名购买网站

.yaml文件实际是用YAML语言编写的&#xff0c;YAML简述。如下 1、语法特点 大小写敏感通过缩进表示层级关系禁止使用tab缩进&#xff0c;只能使用空格键缩进的空格数据不重要&#xff0c;只要相同层级左对齐即可使用#表示注释 2、yaml支持的数据结构有三种&#xff1a;对象、…...

网站后台做图片尺寸是多大/抖音代运营公司

一、HTTP服务器的基本知识 1、Node如何向开发者呈现HTTP请求 Node中的http模块提供了HTTP服务器和客户端接口&#xff1a; var http require(http); 创建HTTP服务器要调用http.createServer()函数。它只有一个函数&#xff0c;是个回调函数&#xff0c;服务器每次收到HTTP请求…...