去年的建軍節,一個展現軍裝照的H5人臉融合遊戲火遍朋友圈,帶來很好的傳播效果。最近歐冠決賽要來了,公司決定作一個尋找和你最像的歐冠球星的H5遊戲,那麼該怎麼作呢?認真分析了一下,這個遊戲其實用到的技術仍是挺多的,是一個比較綜合的項目。主要用到技術以下:css
> 人臉識別
> Python web和Java web
> 域名解析和nginx
> 微信JS
> H5頁面html
人臉識別的API各大平臺都有提供,百度,阿里,優圖(騰訊),Face++. 各家的API大致類似,主要區別只是取的點的個數和返回結果的數據結構,均可用。BAT的都有免費可用(若是對QPS沒有太高要求的話),Face++ 須要收費1元/次(牆裂懷疑失了智)。綜合比較以後選擇使用優圖。
http://open.youtu.qq.com/#/develop/api-face-analysis-detect
SDK下載
http://open.youtu.qq.com/#/develop/tool-sdk
後端採用python,因此下載python版本的SDK。
從優圖獲取的人臉識別以後的信息所有是面部點的信息,須要進行處理,具體的處理方法所有在
https://github.com/tonyiweb/face_merge_master (star,fork來一套?)python
人臉融合大師,能夠知足你10分鐘作出人臉融合功能的理想工具,你值得擁有。ios
基於性能和表現的考慮,作了一個分離。圖片識別和融合的功能所有放在一個Python web項目中,做爲一個api,而後在Java web項目中調用這個API,將返回的結果或者錯誤信息返回到H5頁面。nginx
python是一個能快速開發的語言,有不少易用的web框架可使用,這裏就選擇Tornado這個框架。
服務器上經過nohup python -u run.py& 就能夠啓動一個端口號爲9010(代碼中能夠指定,通常在7000之後)的服務。 nohup能夠保證服務長期後臺運行,而且能夠經過tail -f nohup.out來查看日誌。服務能夠經過ps -ef|grep python查詢服務的pid,再經過kill -9 pid來中止。git
採用SpringBoot搭建的微服務,沒有任何界面。接受H5頁面傳過來的圖片,取調用人臉融合的API,根據結果返回調用結果或者錯誤信息。
github
域名解析的過程其實就是一個經過名字(相對好記一些)找IP地址(相對難以記憶)的過程,而IP地址又對應一臺服務器,也就是經過名字定位服務器。在控制檯的域名解析中新加一條記錄,指向代碼部署的服務器。
由於一臺服務器上實際上是部署多個服務,也會被多個域名所指向,因此其實還須要一個東西來指引服務所要對應的域名,這個東西就是nginx。 一個服務通常是要對應一個端口的,nginx能夠監聽一個端口,而後將這個端口的服務定向到某個域名。
注意:1,https服務須要安全證書,能夠在阿里雲的安全中的CA證書服務中購買(有免費的Symantic的證書)
2,通常默認的是http的,若是沒有必要能夠不用帶安全證書的https服務
3,經過whereis nginx命令查找nginx的位置,經過vhost統一管理nginx配置文件
4,配置完nginx以後,須要重啓nginx服務,命令: ./nginx -s reload 若是沒有錯誤,就說明已經重啓了。web
由於網頁是放在微信環境下傳播的,須要使用到微信的一些基礎功能,如拍照,因此使用微信的JS SDK.
參考文檔:https://www.w3cschool.cn/weixinkaifawendang/h8ap1qe5.html
## 1,配置微信。須要在後臺根據jsapi_ticket等信息生成簽名
(1)前臺
```
//這裏的url爲當前頁面的路徑,爲了使得分享以後的連接也是可用
var url = window.location.href;
$.get(baseUrl+"/common/get_wx_config",{url:url},
function(data){
wx.config({
debug: false, // 開啓調試模式,調用的全部api的返回值會在客戶端alert出來,若要查看傳入的參數,能夠在pc端打開,參數信息會經過log打出,僅在pc端時纔會打印。
appId: data.appId, // 必填,公衆號的惟一標識
timestamp: data.timestamp, // 必填,生成簽名的時間戳
nonceStr: data.nonceStr, // 必填,生成簽名的隨機串
signature: data.signature,// 必填,簽名,
jsApiList: ['checkJsApi','chooseImage','uploadImage','onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareQZone'] // 必填,須要使用的JS接口列表
});
setShareInfo('','');
})
```
(2)後臺,微信簽名過程
後端
## 2,拍照或者從相冊中選擇照片
```
var serverId='0';
function getPic(){
wx.checkJsApi({
jsApiList: ['chooseImage'], // 須要檢測的JS接口列表,全部JS接口列表見附錄2,
success: function(res) {
if(res.checkResult.chooseImage){
wx.chooseImage({
count: 1, // 默認9
sizeType: ['original', 'compressed'], // 能夠指定是原圖仍是壓縮圖,默認兩者都有
sourceType: ['album', 'camera'], // 能夠指定來源是相冊仍是相機,默認兩者都有
success: function (res) {
var localIds = res.localIds; // 返回選定照片的本地ID列表,localId能夠做爲img標籤的src屬性顯示圖片
$("#selfImg").attr("src",localIds);
wx.uploadImage({
localId: localIds[0], // 須要上傳的圖片的本地ID,由chooseImage接口得到
isShowProgressTips: 1, // 默認爲1,顯示進度提示
success: function (res) {
serverId = res.serverId; // 返回圖片的服務器端ID
$("#nextBtn").css("display","block");
}
});
}
});
}else{
showAlert("微信版本太低,沒法使用相機和相冊功能","fail");
}
}
});
}
```
## 3,上傳圖片並得到人臉融合結果
(1)前臺
```
if(serverId!='0'){
if(gender==1){
showAlert("正在玩命給小主兒尋找最像你的球星...","loading");
}else{
showAlert("正在玩命給小主兒尋找最像你的球星太太...","loading");
}
//在服務器端下載圖片,並做人臉融合,返回融合後的結果給img的src
$.get(baseUrl+"/common/download_image",{serverId:serverId,gender:gender},
function(data){
if(data.status=='success'){
hideAlert();
$("#loadingPage").css("display","none");
$("#firstPage").css("display","none");
$("#secondPage").css("display","none");
$("#thirdPage").css("display","block");
var imageData = JSON.parse(data.data);
$("#resultName").html(imageData.modelShortName);
if(gender==1){
$("#discriptionText").html(imageData.description+',要被你迷倒啦(^_-');
setShareInfo(imageData.imageUrl[2],'和我最像的歐冠球星是'+imageData.modelShortName+','+imageData.description)
}else{
$("#discriptionText").html(imageData.modelName+','+imageData.description+',要被你迷倒啦(^_-');
setShareInfo(imageData.imageUrl[2],'和我最像的歐冠女神是'+imageData.modelShortName+','+imageData.description)
}api
$('#firstResultImg').animateCss('fadeIn', function() {
$("#firstResultImg").attr("src",imageData.imageUrl[0]);
$("#firstResultImg").addClass('animated flash');
$("#secondResultImg").animateCss('fadeIn',function(){
$("#secondResultImg").attr("src",imageData.imageUrl[1]);
$("#secondResultImg").addClass('animated flash');
$("#thirdResultImg").animateCss('fadeIn',function(){
$("#thirdResultImg").attr("src",imageData.imageUrl[2]);
$("#thirdResultImg").addClass('animated flash');
$("#fourthResultImg").animateCss('fadeIn',function(){
$("#fourthResultImg").attr("src",imageData.imageUrl[3]);
$("#fourthResultImg").addClass('animated flash');
$("#resultName").addClass('animated bounceIn');
});
});
});
});
}else{
if(gender==1){
showAlert("好遺憾,沒有找到和你相像的球星呢...換張照片,再玩一次吧","fail");
}else{
showAlert("好遺憾,沒有找到和你相像的球星太太呢...換張照片,再玩一次吧","fail");
}
}
})
}else{
showAlert("好遺憾,你尚未上傳任何照片哦...","fail");
}
```
(2)後臺,上傳照片並進行人臉融合
>注意:須要在真機上才能夠調用相機和相冊
>注意:要使用的域名必須在公衆號設置——>功能設置中添加
頁面的大半是要依賴UI設計師,下面放些設計圖,實現過程就省略掉(僞裝不重要~.~)...
後面是製做完成後獲得頁面(請在微信中打開): https://worldcup.superwr.top/index.html
另外還有世界盃的改進版(加入了生成海報圖片和負載均衡):https://worldcup.pro365.cn/index.html
>注意:H5頁面的難點實際上是在於兼容,這裏經過計算設備寬度,獲得相對尺寸rem,而後給元素設置以rem爲單位的位置尺寸等信息,作到所有兼容ios移動設備和大部分Android設備
>注意:頁面中使用到了Animate.css這個CSS動畫框架,連接:http://blog.superwr.top/2018/%E5%8A%A8%E7%94%BB%E6%8F%92%E4%BB%B6animate-css%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E/
我的博客地址:http://blog.superwr.top(不喜勿噴,我的比較懶,噴了也會被忽略。。。)
~。~最後仍是想吐槽一句,爲何不能用markdown呢