##改进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);
}