在微信开发H5页面的时候,往往借助于WeUI或者Jquery WeUI等基础上进行界面效果的开发,由于本人喜欢在Asp.net的Web界面上使用JQuery,因此比较倾向于使用 jQuery WeUI,本篇随笔结合官方案例和自己的项目实际开发过程的经验总结,对在H5页面开发过程中设计到的界面控件进行逐一的分析和总结,以期能够给大家在H5页面开发过程中提供有用的参考。

本篇随笔继续上篇随笔《基于Jquery WeUI的微信开发H5页面控件的经验总结(1)》进行介绍其他部分的内容。

7)条码、二维码生成

在我们做一些扫码操作的时候,我们可能需要根据一些参数生成一些URL,然后生成一个二维码的方式,方便手机扫码直接查看,或者给一些条码设备进行条码的读取,那么这两种情况结合起来就是二维码和条码的处理场景。

例如下面的处方信息展示里面,就需要这样的场景。

二维码QRCode使用的地址是:https://github.com/davidshimjs/qrcodejs

条码JsBarcode使用的地址是:https://github.com/lindell/JsBarcode

使用前,我们引入所需要的qrcodejs和JsBarcode的JS库文件。

<script src="~/Content/JQueryTools/qrcodejs/qrcode.min.js"></script>
<script src="~/Content/JQueryTools/JsBarcode/dist/JsBarcode.all.min.js"></script>

二维码和条码的处理脚本很简单,如下JS代码所示。

//条码
JsBarcode("#barcode", "@ViewBag.Info.PrescriptionNo", {
format: "CODE128",
lineColor: "#0aa",
height: 50,
displayValue: false
}); //二维码
var url = '@ViewBag.WebsiteDomain/h5/PrescriptionDetail?id=@ViewBag.Info.ID';
var qrcode = new QRCode(document.getElementById("qrcode"), {
text: url, //"@ViewBag.Info.PrescriptionNo",
width: 128,
height: 128,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});

使用脚本处理的方式非常不错。

8)JQuery的Ajax/Post/Get等相关处理

在我们前面很多案例代码里面,都采用了JQuery的Ajax/Post/Get/getJSON等函数,它们之间很多时候可以相互替代,差异只是很少的部分。

$.get()方法使用GET方式来进行异步请求,它的语法结构为:$.get( url [, data] [, callback] )。如下代码所示。

$.getJSON()是专门为ajax获取json数据而设置的,并且支持跨域调用,其语法的格式为:getJSON(url,[data],[callback])。

var flowUsers = [];
var url = '/qyh5flow/GetCorpUser';
$.getJSON(url, function (data) {
$.each(data, function (i, item) {
flowUsers.push({
title: item.name, value: item.userid
});
});
$("#txtSelectSignUser").select({
title: "选择会签人员",
items: flowUsers,
multi: true,
//min: 2,
//max: 3,
});
});

$.get()和$.getJSON()两种方法,后者比前者多了一个对返回数据进行JSON转换对象的处理,$.get()方法需要使用下面代码进行JSON的转换。

 var data = $.parseJSON(json);

$.post()方法使用POST方式来进行异步请求,它的语法结构为:$.post(url,[data],[callback],[type]),这个相对于$.get()的操作,使用POST方式提交。

其中的type:type为请求的数据类型,可以是html,xml,json等类型,如果我们设置这个参数为:json,那么返回的格式则是json格式的,如果没有设置,就和$.get()返回的格式一样,都是字符串的。

如下代码是我们使用$.post()的函数进行数据的提交,注意我们也需要使用$.parseJSON进行返回值JSON转换对象的处理。

$.post(url, postData, function (json) {
//转义JSON为对象
var data = $.parseJSON(json);
if (data.Success) {
$.toptip("删除成功!", 'success'); //在界面上找到对应控件ID,移除控件
RemoveImg();
}
else {
$.toast("操作失败:" + data.ErrorMessage, "forbidden");
}
});

$.ajax()是jquery中通用的一个ajax封装,其语法的格式为:$.ajax(options),其中options是一个object类型,它指明了本次ajax调用的具体参数。

一般在使用FormData对象的时候,我倾向于使用$.ajax进行处理,以便更多的弹性化设置。

//提交表单数据和文件
var url = "/qyH5Flow/PaymentSave?userid=@ViewBag.userid";
$.ajax({
url: url,
type: 'post',
processData: false,
contentType: false,
data: formData,
success: function (json) {
//转义JSON为对象
var data = $.parseJSON(json);
if (data.Success) {
$.toast("保存成功,稍后请到列表界面查看。");
}
else {
$.toast("保存失败:" + data.ErrorMessage, "forbidden");
}
}
});

以上就我进行在案例里面使用的各种操作,有时候可以相互替换,根据需要选择不同的操作方式即可。

9)JS脚本的数组对象处理

上面我们使用了各种异步的操作,如JQuery的Ajax/Post/Get/getJSON等函数操作,经常会涉及对数组的遍历处理或者插入处理。

JS数组是一个很的强大的数组对象,支持很多复杂的操作,对数组的操作也是我们经常处理的方式之一。

例如对于返回的数据,我们一般需要进行数组的遍历,然后逐一追加到界面显示,这里就需要使用$.each()函数。

//动态处理图片绑定
$.getJSON("/Qyh5Flow/GetImageList2?attachGuid=" + info.AttachGUID, function (data) {
$.each(data, function (i, item) {
$("#imgAttach").append(`<img class='weui-uploader__file' src='${item.Text}' id='img_${item.Value}'/>`);
});
});

$.each()函数另一个经常使用的场景就是根据JQuery选择器进行元素集合的遍历处理。

var itemCount = 0;
//计算单选框的选中数量
$("input[type='radio']:checked").each(function(){
itemCount += 1;
});
//复选框选中算一个
var chkName = []
$("input[type='checkbox']:checked").each(function () {
var name = $(this).attr('name');
if (chkName.indexOf(name) < 0) {
itemCount += 1;
chkName.push(name);
}
});

我们在需要加入对象的时候,就需要使用push()函数操作了,有时候往往和$.each()函数配合使用。

var items = [];
$.each(data, function (i, item) {
items.push({
title: item.Text, value: item.Value
});
});

或者进行元素遍历查询的时候,如下代码所示。

//构建选中的列表内容
var list = [];
//计算单选框
$("input[type='radio']:checked").each(function () {
list.push($(this).val());
});
//计算复选框
$("input[type='checkbox']:checked").each(function () {
list.push($(this).val());
});

如果我们需要判断某个对象是否在集合里面,我们就会用到$.inArray() 函数进行判断,如下代码所示。

if ($.inArray(key, addKeyList) == -1) {
addKeyList.push(key);
addValueList.push(value);
sendList.push({ key: key, value: value}); $('#tagsToSend').addTag(value);
}

另外,我们对数组还需要了解,如何移除单个或者所有的集合,这个就用到了splice()函数,如下代码所示。

addKeyList.splice(i, 1);//移除某个对象
addValueList.splice(i, 1);//移除某个对象
sendList.splice(i, 1);//移除某个对象

如果需要清空数组,常用的做法如下所示,也是使用splice()函数。

//清空用户选择
function ClearChoice() {
$('#tagsToSend').importTags(''); sendList.splice(0, sendList.length);//待发送的部门、标签、用户列表
addKeyList.splice(0, addKeyList.length);//键的集合
addValueList.splice(0, addValueList.length);//值的集合
}

以上就是我们操作数据的时候,经常使用的一些方法。

10)查询即时列表展示

有时候,我们需要根据查询的条件,对数据库的信息进行检索,然后即时的显示在列表中,供选择使用,如下界面所示。

上图是我项目中,根据拼音码或者名称对药品进行检索,返回的数据进行显示的处理。

为了使用搜索栏,我们使用了微信WeUI定义的搜索栏样式,以下是界面定义的搜索栏DIV层,如下代码。

    <!--搜索栏,类似于微信原生的搜索栏,应用于常见的搜索场景。-->
<div class="weui-search-bar" id="searchBar">
<form class="weui-search-bar__form" onkeydown="if(event.keyCode==13) return false;">
<div class="weui-search-bar__box">
<i class="weui-icon-search"></i>
<input type="search" class="weui-search-bar__input" id="searchInput" placeholder="搜索" required="">
<a href="javascript:clear()" class="weui-icon-clear" id="searchClear"></a>
</div>
<label class="weui-search-bar__label" id="searchText" style="transform-origin: 0px 0px 0px; opacity: 1; transform: scale(1, 1);">
<i class="weui-icon-search"></i>
<span>请输入你想要查看的关键字</span>
</label>
</form>
<a href="javascript:clear()" class="weui-search-bar__cancel-btn" id="searchCancel">取消</a>
</div>

我们在JS代码上执行对应事件的处理,如下所示。

主要就是监控Input控件的内容变化,进行及时的查询和内容展示。

//查询框输入内容触发事件
$('#searchInput').bind('input propertychange', function () {
var name = $("#searchInput").val(); //获取Json对象集合,并生成数据显示内容
var url = "/h5/FindDrugWithPager?page=1&rows=5&Name=" + encodeURI(name);
$.getJSON(url, function (data) {
$("#searchContent").html("");
var html = "";
$.each(data.rows, function (i, item) {
var background = (i % 2 == 0) ? "background-color:Highlight" : "";
html += `<li>
<div class='pic'><img src='@ViewBag.WebsiteDomain/Content/images/drug.png' /></div>
<div class='text'>
<h2><i></i><span>` + item.CommonName + `</span><em>`+ item.Specification +`</em></h2>
<p>商品名:` + item.ProductName + `</p>
<p>厂 家:`+item.Manufacturer +`</p>
</div>
<a class='ture' href=\"javascript:;\" onclick=\"AddDrug('` + item.ID + `','`+ item.ProductName +`')\" ><img src='@ViewBag.WebsiteDomain/Content/images/add1-24.png'></a>
</li>`;
});
$("#searchContent").html(html);
});
}); function cancel() {
$("#searchContent").empty();
} function clear() { $('#searchInput').val('')
$("#searchContent").empty();
}

这里的HTML模板,我们有时候也使用代码块的方式,在模板代码里面插入变量,如下所示。

$.getJSON("/Qyh5Flow/GetImageList2?attachGuid=" + info.AttachGUID, function (data) {
$.each(data, function (i, item) {
$("#previewImage").append(`<img class="weui-preview-box" src='${item.Text}' id='img_${item.Value}'/>`);
});
});

这里的代码块,开始和结束符使用了 ` ` 符号块,其中插入了变量${item.Text} 、${item.Value}等变量字符串,并没有打断模板的内容,如果多行,我们一样的处理,非常方便。

$.getJSON(url, function (data) {
var html = "";
$.each(data.rows, function (i, item) {
html += `<div class="weui-panel weui-panel_access">
<div class="weui-panel__hd">
<span>${item.FormName}</span>:<span>${item.EditorName}</span>,<span>${item.Edittime}</span>
<span class="ord-status-txt-ts fr"><b>${GetStatus(item.Status)}</b></span>
</div>
<div class="weui-media-box__bd pd-10">
<div class="weui-media-box_appmsg ord-pro-list">
<div class="weui-media-box__bd">
<p class="weui-media-box__desc">标题:<span>${item.Title}</span></p>
<div class="clear mg-t-10">
<div class="pro-amount fl"><span class="font-13">当前处理类型:<em class="num font-15">${item.Proc_TypeName}</em></span></div>
<div class="pro-amount fr"><span class="font-13">当前处理人:<em class="name">${item.Proc_UserName}</em></span></div>
</div>
</div>
</div>
</div>
<div class="weui-panel__ft">
<div class="weui-cell weui-cell_access weui-cell_link oder-opt-btnbox">
<a href="${item.ViewUrl}?id=${item.ID}" class="ords-btn-dele">查看详情</a>
</div>
</div>
</div>`;
}); $("#" +divname).html(html);
});

这是我们推荐使用的JS代码块,整块代码都不影响阅读,而且可以换行排版,非常直观。

11)界面弹窗处理

在微信Weui里面定义了几种常规的弹窗处理。

对话框只能通过 JavaScript 进行调用,微信WeUI提供了三种常用的对话框 Alert, Confirm, Prompt 和 Login。我们也可以通过 $.modal 来自定义对话框

实际上, Alert, Confirm, Prompt 和 Login 都是 Modal 的一种定制而已。

一般的JS调用代码如下所示。

//常规提示窗口
$.alert("自定义的消息内容", "自定义的标题"); //确认提示窗口
$.confirm("自定义的消息内容", "自定义的标题", function() {
//点击确认后的回调函数
}, function() {
//点击取消后的回调函数
});

例如我们在流程表单处理里面,会在操作前进行提示用户是否确认处理。

//退回拟稿人重新处理
function ApplyCancel(opinion) {
var tipMessage2 = "数据检查完毕,如确认无误将【退回拟稿人重新处理】,您确实要提交吗?";
$.confirm(tipMessage2, "退回拟稿人重新处理?", function () {
var userid = "@ViewBag.userid";
var applyid = "@Request["id"]";
var url = "/QyH5Flow/SkipFirstApply";
//构造参数发送给后台
var postData = {
userid: userid,
applyId: applyid,
opinion: opinion
};
$.post(url, postData, function (json) {
var data = $.parseJSON(json);
if (data.Success) {
//console.log(data);
//提示处理结果
$.toast("您已经退回经办人进行修改。"); $.closePopup();
initControls();//重新加载
}
else {
$.toast("操作失败:" + data.ErrorMessage);
}
}); }, function () {
//取消操作
});
}

登陆窗口界面效果如下所示。

$.login("自定义的消息内容", function(username, password) {
// 这里进行登录操作
}, function() {
}); //如果参数过多,建议通过 object 方式传入
$.login({
title: '标题',
text: '内容文案',
username: 'tom', // 默认用户名
password: 'tom', // 默认密码
onOK: function (username, password) {
//点击确认
},
onCancel: function () {
//点击取消
}
});

我们可以利用登录框进行一个系统账号的绑定,如下是实际项目的处理代码。

$(document).on('click', '#btnBind', function() {
$.login({
title: '登录',
text: '请输入用户名和密码',
onOK: function (username, password) {
var url = "/H5/VerifyUser?openid=@ViewBag.openid";
var postData = {
username: username,
password: password
}; $.post(url, postData, function (json) {
//转义JSON为对象
var data = $.parseJSON(json);
if (data.Success) {
$.toptip('登录成功!');
location.reload();//刷新页面
//WeixinJSBridge.call('closeWindow');//关闭窗口
}
else {
$.toptip("登录失败:" + data.ErrorMessage, "forbidden");
}
});
},
onCancel: function () {
$.toptip('取消登录!', 'cancel');
}
});
});

上述的几种对话框都是 $.modal 的一种特殊形式。你可以通过 $.modal 来定制对话框

$.modal({
title: "Hello",
text: "我是自定义的modal",
buttons: [
{ text: "支付宝", onClick: function(){ console.log(1)} },
{ text: "微信支付", onClick: function(){ console.log(2)} },
{ text: "取消", className: "default", onClick: function(){ console.log(3)} },
]
});

默认情况下,点击对话框的按钮都会先关闭对话框再触发回调函数。可以通过JS来关闭任何正在显示的对话框:

$.closeModal();

除了上面的几种情况的模态对话框,还有一种是Popup弹出遮盖下面页面的场景,如常规的购物车的情况。

Popup 是一个覆盖式的弹出层,可以完全盖住当前页面或者遮盖一半。

例如我在流程处理页面中,往往需要进行审核、会签处理的时候,弹出对应的处理内容,这个就是Popup的使用场景。

我们通过JS进行调用显示窗口。

$("#SignAction").popup();//主动弹出窗口

其中SignAction层就是一个popup的窗口层,视图HTML代码如下所示。

我们只需要注意到 class='weui-popup__container popup-bottom' 的说明,就知道它的样式了,从底部弹出的Popup窗口。

如果没有加上Popup-bottom的样式,那么就是全屏覆盖的模式。

关闭 Popup

给任何链接加上 class='close-popup' 则点击之后可以关闭当前打开的 popup. 你也可以通过 $.closePopup() 来关闭。 

12)微信JSSDK的整合等处理

微信JSSDK提供了很多丰富的功能,我们可以利用JSSDK实现图片的上传、预览、扫码等操作,图片上传由于我使用了附件上传的方式,因此不在介绍较为繁琐的JSSDK图片上传模式,有兴趣可以参考我之前随笔《微信开发中使用微信JSSDK和使用URL.createObjectURL上传预览图片的不同处理对比》了解下不同。

a) 图片预览

一般我们在一些查看内容的视图界面里面,往往对图片进行预览操作,这时候可以利用JSSDK的图片预览接口,在使用JSSDK接口前,需要进行接口的初始化,然后才能调用,下面是初始化和调用的案例代码。

    <!--微信API初始化-->
<script language="javascript">
var appid = '@ViewBag.appid';
var noncestr = '@ViewBag.noncestr';
var signature = '@ViewBag.signature';
var timestamp = '@ViewBag.timestamp'; wx.config({
debug: false,
appId: appid, // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: noncestr, // 必填,生成签名的随机串
signature: signature, // 必填,签名,见附录1
jsApiList: [
'checkJsApi',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage'
]
}); //所有准备好后,通过样式查找的方式,加入对应集合,然后绑定click事件
wx.ready(function () {
var $images = $(".preview").find("img");
var imgPaths = [];
$images.each(function(){
imgPaths.push(this.src);
}); $images.on("click",function(){
wx.previewImage({
current: this.src,
urls: imgPaths
});
});
});
</script>

而图片的初始化,我们可以在HTML代码进行处理即可。

<div id="previewImage" class="preview">
@if (ViewBag.PresImages != null)
{
for (var i = 0; i < ViewBag.PresImages.Count; i++)
{
<img class="weui-preview-box" src='@ViewBag.PresImages[i]' alt="处方图片">
}
}
</div>

b) 调用扫码处理

我们可以利用JSSDK调用手机的扫码操作,让其进行相应的扫码处理,如下是使用JSSDK进行扫码的JS代码。

    <script language="javascript">
var appid = '@ViewBag.appid';
var noncestr = '@ViewBag.noncestr';
var signature = '@ViewBag.signature';
var timestamp = '@ViewBag.timestamp'; wx.config({
debug: false,
appId: appid, // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: noncestr, // 必填,生成签名的随机串
signature: signature, // 必填,签名,见附录1
jsApiList: [
'checkJsApi',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'scanQRCode'
]
}); //所有准备好后
wx.ready(function () {
document.querySelector('#scancode').onclick = function () {//调用扫码事件返回扫码值
wx.scanQRCode({
needResult: 1,
desc: 'scanQRCode desc',
success: function (res) {
//console.log(res.resultStr);
var isUrl = CheckUrl(res.resultStr);
if (isUrl) {
location.href = res.resultStr;//跳转页面
}
}
});
};
});
//验证URL字符串
function CheckUrl(str) {
var RegUrl = new RegExp();
RegUrl.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\?\/.=]+$");//jihua.cnblogs.com
if (!RegUrl.test(str)) {
return false;
}
return true;
}
</script>

上面扫码后,识别判断URL,如果是URL,那么页面地址自动调整到相应的界面上去。

以上就是一些实际项目中运用到的各种界面处理和JS处理代码,抛砖引玉,希望大家多多支持和鼓励。

基于Jquery WeUI的微信开发H5页面控件的经验总结(2)的更多相关文章

  1. 基于Jquery WeUI的微信开发H5页面控件的经验总结(1)

    在微信开发H5页面的时候,往往借助于WeUI或者Jquery WeUI等基础上进行界面效果的开发,由于本人喜欢在Asp.net的Web界面上使用JQuery,因此比较倾向于使用 jQuery WeUI ...

  2. 基于 jQuery 的专业 ASP.NET WebForms/MVC 控件库!

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  3. 工作小记:企业微信 嵌H5页面 用户权限获取匹配

    一.背景 领导让研究一个活儿:企业微信开发H5应用,微信端客户进入H5页面跟现有的Web系统打通用户权限.通俗的讲:嵌入企业微信H5页面,客户点进去按原权限加载内容.开发者中心有文档,附上两个关键链接 ...

  4. 基于SpringBoot的开源微信开发平台,Jeewx-Boot 1.0 版本发布

    项目介绍 JeewxBoot 是一款基于SpringBoot的免费微信开发平台.支持微信公众号.小程序官网.微信抽奖活动. Jeewx-Boot实现了微信公众号管理.小程序CMS.微信抽奖活动等基础功 ...

  5. offline页面开发常用方法及页面控件验证

    offline页面开发常用方法及页面控件验证,对一些CheckBoxList操作进行封装,新人可以直接使用该代码. 1.返回上一页网址 /// <summary> /// Descript ...

  6. Android微信九宫格图片展示控件

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/214 Android微信九宫格图片展示控件 半年前,公司产 ...

  7. aspx页面控件id上自动加前缀

    公司的一个.net项目,使用的传统aspx页面开发,每个控件上自动加了前缀,最初以为是extjs.net自带的功能,后来研究发现,主要是因为内部使用了母版页.<asp:Content ID=&q ...

  8. Xamarin iOS教程之页面控件

    Xamarin iOS教程之页面控件 Xamarin iOS 页面控件 在iPhone手机的主界面中,经常会看到一排小白点,那就是页面控件,如图2.44所示.它是由小白点和滚动视图组成,可以用来控制翻 ...

  9. RS开发日期提示控件默认为昨天之进阶篇

    时隔<RS开发日期提示控件默认为昨天>这篇博文已经很久了,请原谅我隔了这么久才继续来写这篇笔记.也希望读到这篇笔记的朋友可以从这篇笔记中学习到一些关于RS日期控件和JS的一些应用知识,当然 ...

随机推荐

  1. 通用 mapper的简单使用

    通用 MAPPER的简单使用 官方  https://mapperhelper.github.io/docs/2.use/ 依赖 <dependency> <groupId>t ...

  2. 序列化模块ModelSerializer上补充及ListSerializer

    整体单改 路由层.模型层.序列化层不需要做修改,只需要处理视图层:views.py """ 1) 单整体改,说明前台要提供修改的数据,那么数据就需要校验,校验的数据应该在 ...

  3. mysql-5.7.25解压版本安装和navicat 12.1版本破解-4.8破解工具

    1.配置环境变量 百度网盘下载https://pan.baidu.com/s/1tbOJiOG9l87HbIzsLApX4A 提取码  t657  (mysql-5.7.25大小300M解压后1.6G ...

  4. centos7限制普通用户访问单一目录下的单一文件

    要求给开发同事开设一个查看日志的账号,并限制其只能访问该目录下的单一文件 1.先新建账号 useradd loglook passwd loglook 家目录为/home/loglook 2.日志的属 ...

  5. Welcome to Erhan Blog

    "Yeah It's on. " 前言 Erhan 的 Blog 就这么开通了. 跳过废话,直接看技术实现 2018 年,Hux 总算有个地方可以好好写点东西了. 作为一个程序员, ...

  6. Linux用户与用户组的关系

    一.用户和用户组文件 1. /etc/passwd:所创建的用户账号和信息均存放在次文件中,所有用户可读取: 最后一个字段的值一般为/sbin/nologin,表示该账号不能用来登陆linux系统: ...

  7. doctrine queryBuilder

    为了能够方便的切换数据库,我们有必要使用doctrine的queryBuilder, 但是估计很多人都是不喜欢的(我也是),之前尝试用的时候,发现在doctrine定义的SELECT语法中并没有CON ...

  8. 不同浏览器Cookie大小

    一.浏览器允许每个域名所包含的 cookie 数:Microsoft 指出 Internet Explorer 8 增加 cookie 限制为每个域名 50 个,但 IE7 似乎也允许每个域名 50 ...

  9. 图示JVM工作原理

    JDK,JRE,JVM的联系是啥? JVM Java Virtual Machine JDK Java Development Kit JRE Java Runtime Environment 看上图 ...

  10. python webp转jpg

    webp格式转jpg格式 从网页上保存下来的webp格式的图片用ps和一些看图软件打不开,所以需要进行下转换. 直接上py代码.代码用到了PIL库,如果电脑上没有还需要pip install Pill ...