##改進Face/Detect
現在Face/Detect和Face/Verify將支持將用戶提交的結果持久化。我們先考慮下Face/Detect現在的變化,原先我們的流程是:從微信客戶端獲得mediaID,通過這個mediaID從微信服務器下載圖片,然後將這個圖片提交給牛津,以獲得FaceID
現在我們需要考慮的更周到了:當從微信客戶端得到mediaID,我們需要查看下本地文件夾中是否有匹配的文件,在提交給牛津之前我們也需要從Mango數據庫中查詢是否有匹配的上次的提交結果
我們先改進微信服務的代碼,使得只有Mongo沒有存儲mediaID和對應的文件再從微信的服務器去下載圖片
public async Task<string> Get(string mediaid)
{
var mongo = new MongoDBHelper("weixinImgFile");
//查詢mongo中是否存儲了mediaid對應的照片文件
var doc = await mongo.SelectOneAsync(x => x["mediaid"] == mediaid);
if (doc != null)
{
return doc["filename"].ToString();
}
//http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
var queryString = HttpUtility.ParseQueryString(string.Empty);
queryString["access_token"] = await Get();
queryString["media_id"] = mediaid;
var uri = "http://file.api.weixin.qq.com/cgi-bin/media/get?" + queryString;
HttpResponseMessage response;
response = await client.GetAsync(uri);
var msg = await response.Content.ReadAsStreamAsync();
var fileName = response.Content.Headers.ContentDisposition.FileName.Replace("\"", "");
var helper = new ProjecToxfordClientHelper();
var content = await FileHelper.ReadAsync(msg);
FileHelper.SaveFile(content, fileName);
await mongo.InsertAsync(Newtonsoft.Json.JsonConvert.SerializeObject(
new {
Mediaid = mediaid,
FileName = fileName
}
));
return fileName;
}
然後我們來改進FaceController的DetectAPI,使得先在Mongo中查詢對應照片的分析結果,當沒有之前查詢的結果,再去牛津進行分析。
[HttpGet]
[Route("face/detect/{weixnmediaid}")]
public async Task<HttpResponseMessage> Detect(string weixnmediaid)
{
var key = "detect";
//得到從微信服務器下載的文件名
var fileName = await new WeixinController().Get(weixnmediaid);
var mongo = new MongoDBHelper<DetectResultModels>("facedetect");
//照片之前有沒有下載過
var docArr = await mongo.SelectMoreAsync(x => x.FileName == fileName);
if (docArr.Count > 0)
{
var resultJson = docArr.Select(
doc => new
{
faceId = doc.faceId,
filename = doc.FileName,
age = doc.Age,
gender = doc.Gender,
smile = doc.Smile
}
).ToJson();
return client.CreateHttpResponseMessage(
Request,
new Models.ProjecToxfordResponseModels(resultJson, HttpStatusCode.OK));
}
//如果Mongo中沒有該照片對應的Face信息
var content = await FileHelper.ReadAsync(fileName);
if (content != null)
{
var result = await client.PostAsync(key,
content,
new Dictionary<string, string> {
{"returnFaceId","true"},
{"returnFaceLandmarks","flase"},
{"returnFaceAttributes","age,gender,smile"}
}
);
if (result.StatusCode == HttpStatusCode.OK)
{
var tmpJArr = Newtonsoft.Json.Linq.JArray.Parse(result.Message);
//將牛津結果寫入數據庫
foreach (var tmp in tmpJArr)
{
await mongo.InsertAsync(new DetectResultModels()
{
FileName = fileName,
faceId = (string)tmp["faceId"],
Age = (double)tmp["faceAttributes"]["age"],
Gender = (string)tmp["faceAttributes"]["gender"],
Smile = tmp["faceAttributes"]["smile"] != null ? (double)tmp["faceAttributes"]["smile"] : 0
});
}
var resultJson = tmpJArr.Select(x => new
{
faceId = x["faceId"],
age = (double)x["faceAttributes"]["age"],
gender = (string)x["faceAttributes"]["gender"],
smile = x["faceAttributes"]["smile"] != null ? (double)x["faceAttributes"]["smile"] : 0
}).ToJson();
return client.CreateHttpResponseMessage(
Request,
new Models.ProjecToxfordResponseModels(resultJson, HttpStatusCode.OK));
}
}
throw new HttpResponseException(HttpStatusCode.BadRequest);
}