人脸识别活体检测之张张嘴和眨眨眼

【这段时间有点忙,终于截止今天2018.06.22完成了人脸识别的最后一道程序——活体检测之眨眨眼和张张嘴】

关于人脸识别的内容我之前也写过好几篇博文,其中有: 
{java实现人脸识别源码} 
{C#winforms实现windows窗体人脸识别} 
{人脸识别活体检测测试案例} 
大家可以去看看,其中兼容性也比较良好,支持常用浏览器,火狐、谷歌、360、UC浏览器以及opera浏览器,源码也已经上传成功,所需要的JS文件和jar也都上传到资源页。

好了,我们废话不多说,先来说说今天的内容。 
眨眨眼和张张嘴在哪里用的到呢?如果大家不知道其他的软件,大家肯定知道支付宝软件吧,其中支付宝软件登陆的时候就会语音提示眨眨眼和张张嘴来验证是不是本人登陆(限制照片登陆) 

以前刚开始写的时候我写的人脸识别用照片也可以识别,然后好多粉丝留言说这太不安全了,还有几个用嫌弃的眼神对我说:你这做的还有啥用,我拿着你的照片来登陆,居然能登陆成功,还不如以前的密码登陆安全呢。(其实他没做出来~),我也没说啥,毕竟是自己做的不完善呢,忍气吞声继续深入研究。终于做出来了后来的活体检测,也就是上面的第二个链接! 但是…… 这个活体检测有时候会失误!会失误!会失误!!! 这是个很大的bug,于是我就开始开发现在的眨眨眼和张张嘴~


一、首先我来说一下运行过程:

首先进入页面,login.jsp中,点击检测按钮 

接着你会听到语音提示:现在请张张嘴(这个语音提示可是专门找美女录得音呢~) 
你就按照语音提示张张嘴就可以了,张合张合重复一遍就大概可以验证成功了,接着你就会听见语音提示:现在请眨眨眼,这时候你眨眨眼就行了,验证通过会进入我的网站,期间如果你的脸没有放置好的话就会提示: 

当你看到提示这个的时候你把脸调整的放到框内就可以了。实在不行你就刷新一下网页重新来一遍吧。


二、技术分析

技术方面有以下几个步骤:

第一,js调用前台摄像头读取人脸信息,提交到后台的FaceServlet中,通过ajax进行交互,参数分别是:

type : “post”,//提交方式

url : “faceServlet”,//请求地址

data : { 

“img” : imgData1, 

“tag” : “eye”//区分是眨眼还是张嘴 

}//数据

4.dataType : “json” 

上面就是ajax请求的参数,然后写个回调函数就可以了。 

第二、拿着Base64图像数据之后去检测去,检测回来的数据如下所示:


“timestamp”: 1528371144, 
“result”: { 
“face_list”: [{ 
“expression”: { 
“probability”: 0.9999684095, 
“type”: “none” 
}, 
“face_probability”: 0.9626089931, 
“glasses”: { 
“probability”: 0.9998494387, 
“type”: “common” 
}, 
“location”: { 
“height”: 307, 
“rotation”: 2, 
“width”: 273, 
“left”: 296.1046143, 
“top”: 163.5777588 
}, 
“landmark72”: [ 

“y”: 241.360199, 
“x”: 292.4519043 
}, 

“y”: 284.3699341, 
“x”: 295.9116211 
}, 

“y”: 328.4156189, 
“x”: 304.021759 
}, 

“y”: 371.3819275, 
“x”: 314.0935364 
}, 

“y”: 416.5806274, 
“x”: 333.3151245 
}, 

“y”: 459.6279297, 
“x”: 370.47229 
}, 

“y”: 476.2438354, 
“x”: 412.0462036 
}, 

“y”: 469.1072998, 
“x”: 457.7119141 
}, 

“y”: 435.0166626, 
“x”: 501.7189941 
}, 

“y”: 390.2756348, 
“x”: 532.2461548 
}, 

“y”: 345.0927124, 
“x”: 548.138916 
}, 

“y”: 299.1921692, 
“x”: 559.2930298 
}, 

“y”: 254.285141, 
“x”: 565.3004761 
}, 

“y”: 230.1785583, 
“x”: 329.6694946 
}, 

“y”: 222.2650757, 
“x”: 343.285614 
}, 

“y”: 220.7796631, 
“x”: 356.7460938 
}, 

“y”: 223.9135742, 
“x”: 371.3406677 
}, 

“y”: 233.6182861, 
“x”: 385.2095947 
}, 

“y”: 235.2540588, 
“x”: 370.6172485 
}, 

“y”: 236.2314148, 
“x”: 356.4389343 
}, 

“y”: 234.2461243, 
“x”: 341.9369507 
}, 

“y”: 227.4796143, 
“x”: 355.9927368 
}, 

“y”: 193.4365387, 
“x”: 313.8055115 
}, 

“y”: 170.465332, 
“x”: 331.9764404 
}, 

“y”: 166.3371429, 
“x”: 356.399353 
}, 

“y”: 170.4036255, 
“x”: 380.4868774 
}, 

“y”: 188.2350311, 
“x”: 401.4260559 
}, 

“y”: 188.1490021, 
“x”: 379.4369202 
}, 

“y”: 186.7609863, 
“x”: 356.0379028 
}, 

“y”: 188.6333923, 
“x”: 333.6030884 
}, 

“y”: 237.4863892, 
“x”: 465.0245972 


“y”: 192.1312256, 
“x”: 450.9655762 
}, 

“y”: 176.1939087, 
“x”: 474.1013794 

“x”: 375.137085 
}, 

“y”: 363.3876343, 
“x”: 393.6142578 
}, 

“y”: 360.5367126, 
“x”: 422.6240845 
}, 

“y”: 366.1363525, 
“x”: 451.1436768 
}, 

“y”: 389.2103271, 
“x”: 469.8604736 
}, 

“y”: 407.2568359, 
“x”: 450.6833191 
}, 

“y”: 413.2620239, 
“x”: 420.4364014 
}, 

“y”: 403.9484863, 
“x”: 390.8678589 
}, 

“y”: 377.3647461, 
“x”: 396.2229004 
}, 

“y”: 376.8469238, 
“x”: 421.9415588 
}, 

“y”: 379.1690674, 
“x”: 447.9805908 
}, 

“y”: 390.7108154, 
“x”: 446.4016724 
}, 

“y”: 391.1112061, 
“x”: 421.5936279 
}, 

“y”: 388.0070801, 
“x”: 396.4388733 

], 
“face_token”: “05f2d8abe9fb3ff0a7b2e590c3af1b94”, 
“face_shape”: { 
“probability”: 0.5348426104, 
“type”: “oval” 
}, 
“race”: { 
“probability”: 0.9990831614, 
“type”: “yellow” 
}, 
“angle”: { 
“yaw”: 0.9113687873, 
“roll”: 2.805583239, 
“pitch”: -3.07931757 
}, 
“landmark”: [ 

“y”: 227.4796143, 
“x”: 355.9927368 
}, 

“y”: 233.886261, 
“x”: 491.254364 
}, 

“y”: 305.3646545, 
“x”: 421.223877 
}, 

“y”: 385.065155, 
“x”: 421.7819214 

], 
“, 
“quality”: { 
“completeness”: 1, 
“occlusion”: { 
“left_eye”: 0, 
“chin_contour”: 0.2168905884, 
“mouth”: 0, 
“right_cheek”: 0.02743142098, 
“left_cheek”: 0.01728247851, 
“nose”: 0.08578856289, 
“right_eye”: 0 
}, 
“blur”: 8.371096101E-7, 
“illumination”: 54 
}, 
“face_type”: { 
“probability”: 0.9988574386, 
“type”: “human” 

}], 
“face_num”: 1 
}, 
“cached”: 0, 
“error_code”: 0, 
“log_id”: 2850674365, 
“error_msg”: “SUCCESS” 
}

看到上面的json数据,我当时一看是懵逼的状态,这json解析起来有点费力,经过一番折腾,终于可以解析出来了,其中解析方法如下:public static Landmark  parsingFaceJson(JSONObject json_str){Landmark landmark = new Landmark();//开始解析json//JSONObject  dataJson=new JSONObject(json_str);//找到result节点JSONObject  response_result=json_str.getJSONObject("result");//继续找face_list节点JSONArray face_list_jsonArray=response_result.getJSONArray("face_list");JSONObject face_list_jsonObject=face_list_jsonArray.getJSONObject(0);//找到landmark(关键点)节点,4个关键点位置,左眼中心、右眼中心、鼻尖、嘴中心final JSONArray landmark_jsonArray=face_list_jsonObject.getJSONArray("landmark");//左眼中心landmark.setLeft_eye_zhongxin(new ArrayList<Double>(){{add((Double) landmark_jsonArray.getJSONObject(0).get("y")); add((Double) landmark_jsonArray.getJSONObject(0).get("x"));}});//右眼中心landmark.setRight_eye_zhongxin(new ArrayList<Double>(){{add((Double) landmark_jsonArray.getJSONObject(1).get("y")); add((Double) landmark_jsonArray.getJSONObject(1).get("x"));}});//鼻尖landmark.setNose_zhongxin(new ArrayList<Double>(){{add((Double) landmark_jsonArray.getJSONObject(2).get("y")); add((Double) landmark_jsonArray.getJSONObject(2).get("x"));}});//嘴中心landmark.setMouse_zhongxin(new ArrayList<Double>(){{add((Double) landmark_jsonArray.getJSONObject(3).get("y")); add((Double) landmark_jsonArray.getJSONObject(3).get("x"));}});//继续找landmark72节点final JSONArray landmark72_jsonArray=face_list_jsonObject.getJSONArray("landmark72");//左眼上边landmark.setLeft_eye_top(new ArrayList<Double>(){{add((Double) landmark72_jsonArray.getJSONObject(14).get("y")); add((Double) landmark72_jsonArray.getJSONObject(14).get("x"));}});//左眼下边landmark.setLeft_eye_bottom(new ArrayList<Double>(){{add((Double) landmark72_jsonArray.getJSONObject(19).get("y")); add((Double) landmark72_jsonArray.getJSONObject(19).get("x"));}});//右眼上边landmark.setRight_eye_top(new ArrayList<Double>(){{add((Double) landmark72_jsonArray.getJSONObject(32).get("y")); add((Double) landmark72_jsonArray.getJSONObject(32).get("x"));}});//右眼下边landmark.setRight_eye_bottom(new ArrayList<Double>(){{add((Double) landmark72_jsonArray.getJSONObject(36).get("y")); add((Double) landmark72_jsonArray.getJSONObject(36).get("x"));}});//嘴巴上边landmark.setMouse__top(new ArrayList<Double>(){{add((Double) landmark72_jsonArray.getJSONObject(60).get("y")); add((Double) landmark72_jsonArray.getJSONObject(60).get("x"));}});//嘴巴下边landmark.setMouse__bottom(new ArrayList<Double>(){{add((Double) landmark72_jsonArray.getJSONObject(70).get("y")); add((Double) landmark72_jsonArray.getJSONObject(70).get("x"));}});return landmark;}

其中的Landmark 类型 是个实体类,实体类的源码请参考本文末~ 
解析完json就可以分析数据了,当时在此处遇到了个难点,很是想不通的一个逻辑,于是就去各大java群里面进行提问,功夫不负有心人,遇到一大佬给我话了个图解决了我当时的难点,(这边要特别鸣谢一下大佬!!)图: 

光看图大家肯定看不明白,我在这里先解释一下吧,我当时的思路是:前台通过定时器,每1s进行提交一次图像数据,然后在后台进行比较上一次执行结果和下一次执行结果的值,然后想不通这里面的业务是什么样子的,于是就有了上面的这张图。

第三、分析数据:

张嘴:通过json获取嘴中心的点和上边、下边的位置,张嘴和闭嘴是有差别的,差别如下(解析的json数据):

嘴巴分析:----闭着嘴巴:第一次的上嘴唇:361.1332397
第一次的嘴唇中心:378.8190308
第一次的下嘴唇:382.1697388上中:17
下中:4第一次的上嘴唇:390.951355
第一次的嘴唇中心:409.0862122
第一次的下嘴唇:414.6711731上中:19
下中:5第一次的上嘴唇:402.4402466
第一次的嘴唇中心:417.4428406
第一次的下嘴唇:419.6887207上中:15
下中:2第一次的上嘴唇:403.1029358
第一次的嘴唇中心:419.4420166
第一次的下嘴唇:424.0343018上中:16
下中:5第一次的上嘴唇:445.7279663
第一次的嘴唇中心:455.8665161
第一次的下嘴唇:457.3482971上中:10
下中:2第二次的上嘴唇:454.5872192
第二次的嘴唇中心:462.1132812
第二次的下嘴唇:463.1278381上中:8
下中:1

上中:嘴唇上边与嘴唇中心的距离 
下中:嘴唇下边与嘴唇中心的距离

眨眼:正常人的眼镜都是有两只(左眼和右眼),所以这边我们比较的时候就比张嘴验证麻烦了,思路还是和张嘴的思路是一样的,下面的返回解析的分析数据:

***********************************************************************************闭着眼的左眼上边:250.549469
闭着眼的左眼中间:252.7034607
闭着眼的左眼下边:258.3751831
闭着眼的左眼上边与中间的值:2.153991700000006
闭着眼的左眼下边与中间的值:5.6717224000000215
闭着眼的右眼上边:248.886261
闭着眼的右眼中间:251.9490204
闭着眼的右眼下边:257.2275391
闭着眼的右眼上边与中间的值:3.0627594000000045
闭着眼的右眼下边与中间的值:5.2785187000000064闭着眼的左眼上边:236.7052612
闭着眼的左眼中间:239.7859192
闭着眼的左眼下边:245.471283
闭着眼的左眼上边与中间的值:3.0806579999999997
闭着眼的左眼下边与中间的值:5.685363800000005
闭着眼的右眼上边:234.837738
闭着眼的右眼中间:238.6846619
闭着眼的右眼下边:244.2976685
闭着眼的右眼上边与中间的值:3.8469239000000073
闭着眼的右眼下边与中间的值:5.613006599999977闭着眼的左眼上边:245.0596619
闭着眼的左眼中间:246.9369202
闭着眼的左眼下边:252.2763367
闭着眼的左眼上边与中间的值:1.877258299999994
闭着眼的左眼下边与中间的值:5.339416499999999
闭着眼的右眼上边:241.4249573
闭着眼的右眼中间:244.3227234
闭着眼的右眼下边:249.2035217
闭着眼的右眼上边与中间的值:2.8977661000000126
闭着眼的右眼下边与中间的值:4.880798300000009*********************************************************************************
闭着眼的左眼上边与中间的值:2.843383799999998
闭着眼的左眼下边与中间的值:6.379211400000003
闭着眼的右眼上边与中间的值:3.6415863
闭着眼的右眼下边与中间的值:5.569457999999997
闭着眼的左眼上边与中间的值:7.1395263
闭着眼的左眼下边与中间的值:8.606811599999986
闭着眼的右眼上边与中间的值:7.101028499999984
闭着眼的右眼下边与中间的值:7.526168800000022
闭着眼的左眼上边与中间的值:4.141037000000011
闭着眼的左眼下边与中间的值:7.363510200000007
闭着眼的右眼上边与中间的值:4.587234499999994
闭着眼的右眼下边与中间的值:6.540771500000034
闭着眼的左眼上边与中间的值:2.4197997999999643
闭着眼的左眼下边与中间的值:5.460693300000003
闭着眼的右眼上边与中间的值:2.9811705999999845
闭着眼的右眼下边与中间的值:4.65585329999999

上面数据一大推,大家看出来个123就行了。 
验证成功返回前台就行了。


关键代码贴上来: 
张张嘴的验证:

/*** * @Description: 该方法的主要作用:张张嘴验证* @Title: face_jiance* @param  @param img* @param  @param response* @param  @param request 设定文件  * @return  返回类型:void   * @throws* 个人博客:https://blog.csdn.net/qq_34137397*/private void face_mouse(String img, HttpServletResponse response,HttpServletRequest request) {        /*if (dataMap.get(1) == null) {// 第一次请求landmark = face_jiance(img);System.out.println("第一次的上嘴唇:"+landmark.getMouse__top().get(0));System.out.println("第一次的嘴唇中心:"+landmark.getMouse_zhongxin().get(0));System.out.println("第一次的下嘴唇:"+landmark.getMouse__bottom().get(0));dataMap.put(1, landmark);} else {*/// 不是第一次请求Landmark landmark_next = face_jiance(img);            // 和前一次的数据进行比较//Landmark landmark_pre = (Landmark) dataMap.get(1);// 嘴唇上面的位置相对于中心点对比PrintWriter writer;            if ((landmark_next.getMouse_zhongxin().get(0) - landmark_next.getMouse__top().get(0)) > 40&&(landmark_next.getMouse__bottom().get(0) - landmark_next.getMouse_zhongxin().get(0)) > 30) {                    try {writer = response.getWriter();writer.print("1");} catch (IOException e) {                        // TODO 异常执行块!e.printStackTrace();}}else{                try {writer = response.getWriter();writer.print("0");} catch (IOException e) {                    // TODO 异常执行块!e.printStackTrace();}}            //dataMap.put(1,landmark_next);         //放进去  方便下次进行比较}    /*}*/

眨眨眼的验证代码:

/*** * @Description: 该方法的主要作用:眨眼对比* @Title: face_eye* @param  @param img* @param  @param response* @param  @param request 设定文件  * @return  返回类型:void   * @throws* 个人博客:https://blog.csdn.net/qq_34137397*/private void face_eye(String img, HttpServletResponse response,HttpServletRequest request) {Landmark landmark_next = face_jiance(img);System.out.println("闭着眼的左眼上边与中间的值:"+((landmark_next.getLeft_eye_zhongxin().get(0))-(landmark_next.getLeft_eye_top().get(0))));System.out.println("闭着眼的左眼下边与中间的值:"+((landmark_next.getLeft_eye_bottom().get(0))-(landmark_next.getLeft_eye_zhongxin().get(0))));System.out.println("闭着眼的右眼上边与中间的值:"+((landmark_next.getRight_eye_zhongxin().get(0))-(landmark_next.getRight_eye_top().get(0))));System.out.println("闭着眼的右眼下边与中间的值:"+((landmark_next.getRight_eye_bottom().get(0))-(landmark_next.getRight_eye_zhongxin().get(0))));System.out.println("__________________________________________________");PrintWriter writer;if ((landmark_next.getLeft_eye_zhongxin().get(0))- (landmark_next.getLeft_eye_top().get(0)) < 6&& (landmark_next.getRight_eye_zhongxin().get(0))- (landmark_next.getRight_eye_top().get(0)) < 6) {System.out.println("进来了上边验证成功");// 继续判断下边的if ((landmark_next.getLeft_eye_bottom().get(0))- (landmark_next.getLeft_eye_zhongxin().get(0)) < 6.6&& (landmark_next.getRight_eye_bottom().get(0))- (landmark_next.getRight_eye_zhongxin().get(0)) < 6.6) {System.out.println("进来了下边验证成功");try {writer = response.getWriter();writer.print("1");} catch (IOException e) {// TODO 异常执行块!e.printStackTrace();}} else {try {writer = response.getWriter();writer.print("0");} catch (IOException e) {// TODO 异常执行块!e.printStackTrace();}}}}

最后上传源码【请点击阅读原文获取源码】:

感谢您抽出  · 来阅读此文

更多精彩请点击【阅读原文】哦

↓↓↓

青鸟IT汇,一个专注于IT技术和互联网资讯的公众号欢迎大家的关注!!!

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

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

相关文章

PHP WEB程序设计信息表,PHP WEB程序设计

学习情境1 PHP运行环境搭建1.1 任务引入1.2 任务分析1.2.1 任务目标1.2.2 设计思路1.3 任务实施任务1 WAMP插件方式手动安装任务2 WAMPServer集成环境安装任务3 WAMP常用环境配置1.4 任务小结1.5 知识拓展1.5.1 PHP简介1.5.2 B&#xff0f;S相关知识1.5.3 PHP开发…

让智能机器人更智能

Microsoft Bot Framework、LUIS、Azure Bot Service 和 Azure Functions 均已推出。最近到处有人在说&#xff1a;智能机器人是新应用。原因之一就是&#xff0c;智能机器人能够让你轻松、高效地完成常见任务。想一想&#xff1a; 只需让某种数字助理为你执行相关操作&#xff…

MySQL extract()函数

转载自 MySQL extract()函数 简介MySQL EXTRACT函数 EXTRACT()函数提取日期的一部分。下面说明了EXTRACT()函数的语法。 EXTRACT(unit FROM date)EXTRACT()函数需要两个参数&#xff1a;unit和date。 unit是要从日期中提取的间隔。 以下是unit参数的有效间隔。 DAYDAY_H…

2017蓝桥杯省赛---java---C---7 Excel地址)

题目描述 Excel单元格的地址表示很有趣&#xff0c;它使用字母来表示列号。 比如&#xff0c; A表示第1列&#xff0c; B表示第2列&#xff0c; Z表示第26列&#xff0c; AA表示第27列&#xff0c; AB表示第28列&#xff0c; BA表示第53列&#xff0c; …当然Excel的最大列号是…

oracle8修改最大连接数,ORACLE查看并修改最大连接数的具体步骤

第一步,在cmd命令行&#xff0c;输入sqlplus第二步&#xff0c;根据提示输入用户名与密码1. 查看processes和sessions参数SQL> show parameter processesNAME TYPE VALUEdb_writer_processes integer 1gcs_serve…

Excel的基础操作

一、Excel的界面组成部分&#xff1a;标题栏、功能选项卡、单元格名称、功能面板、编辑栏、工 作导航按钮、工作表标签 二、一个工作薄默认包含三个工作表&#xff0c;可以自己添加工作表 三、单元格操作&#xff1a;1.编辑内容&#xff1a;(1)单击需要添加内容的单元格–》输…

MySQL now()函数

转载自 MySQL now()函数 MySQL NOW()函数简介 MySQL NOW()函数以"YYYY-MM-DD HH:MM:DD"或"YYYYMMDDHHMMSS.uuuuuuu"格式的字符串或数字返回配置的时区中的当前日期和时间。 NOW()函数的返回类型取决于使用它的上下文。 例如&#xff0c;在以下语句中&a…

有效事件: 可取代数十种设计模式

编辑寄语 当我让 MSDN 杂志高级特约编辑 James McCaffrey 审阅本文的初稿时&#xff0c;他为本文作者提出的一些观点和想法所震怒&#xff0c;愤愤然地离开了。大多数时候&#xff0c;这预示着文稿不通过。但 McCaffrey 指出&#xff0c;软件工程中的新概念遭到摒弃再常见不过&…

2018蓝桥杯省赛---java---C---1(哪天返回)

题目描述 代码实现 package TEST;public class Main {public static void main(String[] args) {int i1,num1,sum1;//num每天挣的钱&#xff0c;sum总共挣的钱while (sum<108){sum(num2);i;//表示天数}System.out.println(i);} }答案 11

expect() php,Linux expect 的安装

expect是建立在tcl基础上的一个工具&#xff0c;它还提供了一些Tcl所没有的命令&#xff0c;它可以用来做一些linux下无法做到交互的一些命令操作&#xff0c;在远程管理方面发挥很大的作用。因为expect是基于tcl的&#xff0c;所以需要你的系统中安装有tcl如何检查&#xff1f…

PS中缩放工具的细微缩放不可以使用的解决方法

我的PS中的细微缩放是灰色的&#xff0c;就像是这样的&#xff1a; 那么怎么办呢&#xff1f; 解决方法如下&#xff1a; 1.点击PS菜单栏中的“编辑”–>首选项–>性能–》然后吧【启动OpenGL绘图】的复选框勾选上–>确定。 2.重新打开图片就可以了。 希望对大家…

MySQL month()函数

转载自 MySQL month()函数 MySQL MONTH函数介绍 MONTH函数返回一个整数&#xff0c;表示指定日期值的月份。 以下说明了MONTH函数的语法&#xff1a; MONTH(date);MONTH函数接受一个DATE或DATETIME值的参数。 它返回1到12之间的整数&#xff0c;范围从1到12。 如果通过零日…

263. 丑数---LeetCode---JAVA

class Solution {public boolean isUgly(int n) {while(n>0){if(n%20){n/2;}else if(n%30){n/3;}else if(n%50){n/5;}else{break;}}return n1;} }

老司机实战Windows Server Docker:3 单节点Windows Docker服务器简单运维(上)

经过上两篇实战Windows Server Docker系列文章&#xff0c;大家对安装Windows Docker服务以及如何打包现有IIS应用为docker镜像已经有了基本认识。接下来我们来简单讲讲一些最基本的运维问题。鉴于到目前为止我们只谈到单服务器部署。这里暂时不涉及集群模式下的复杂生产环境运…

ps中扩展画布的时候,不能选择扩展画布部分的颜色解决方法

在PS中&#xff0c;我们有时候会遇到扩展画布的场景&#xff0c;但是扩展完画布之后我们发现不能改变颜色&#xff0c;这可怎么办。 首先来看一下是什么样的问题&#xff1a; 这个背景是不能选择的。 问题分析&#xff1a;这是因为你创建的画布的时候颜色是透明色的&#xff0…

oracle 删除时间段的,oracle SQL如何从日期中删除时间

我有一个名为StartDate的列&#xff0c;其中包含以下格式的日期&#xff1a;03-03-2012 15:22我需要的是将其转换为日期。应该是这样的&#xff1a;DD / MM / YYYY我没有成功尝试过的是&#xff1a;selectp1.PA_VALUE as StartDate,p2.PA_VALUE as EndDatefrom WP_Work pLEFT J…

MySQL str_to_date()函数

转载自 MySQL str_to_date()函数 MySQL STR_TO_DATE函数简介 下面说明了STR_TO_DATE()函数的语法&#xff1a; STR_TO_DATE(str,fmt);STR_TO_DATE()根据fmt格式字符串将str字符串转换为日期值。 STR_TO_DATE()函数可能会根据输入和格式字符串返回DATE&#xff0c;TIME或DAT…

异或运算(^)

针对二进制&#xff0c;相同的为0&#xff0c;不同的为1 注意事项 前提i位置的数不等于j位置的数 public static void swap(int[] arr,int i,int j){arr[i]arr[i]^arr[j];arr[j]arr[i]^arr[j];arr[i]arr[i]^arr[j];}

jQuery遍历div,判断是否为空,为空时执行某个操作

以下运行结果&#xff1a; 代码如下&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><link rel"stylesheet" type"text/css" href"css/css.css"/>&l…

Dapper源码学习和源码修改

之前ORM比较火热&#xff0c;自己也搞了个WangSql&#xff0c;但是感觉比较low&#xff0c;大家都说Dapper性能好&#xff0c;所以现在学习学习Dapper&#xff0c;下面简单从宏观层面讲讲我学习的Dapper。 再了解一个东西前&#xff0c;先得学会使用&#xff0c;我也不再赘述怎…