public string[] ProcessImage(string rawDataUrl, out string intermediateUrl, out string finalUrl, out bool addedOverlay)
{
intermediateUrl = null;
addedOverlay = false;
var ctx = new FCClient(_apiKey, _apiSecret);
string contentType;
var data = GetDataFromUrl(rawDataUrl, out contentType);
var dataToSend = ResizePictureForDetection(data);
if (null == _possibleUsers)
{
_possibleUsers = Task.Run(async () => await ctx.Account.UsersAsync(new [] { _tagNamespace })).Result.Users[_tagNamespace].Select(i => i.Split('@')[0]).ToArray();
}
using (var ms = new MemoryStream(data))
{
var image = (Bitmap)Bitmap.FromStream(ms);
new ContrastStretch().ApplyInPlace(image);
List<Tag> faceTags = null;
try
{
var detectResult = Task.Run(async () =>
{
using (var msToSend = new MemoryStream(dataToSend))
{
return await ctx.Faces.RecognizeAsync(_possibleUsers, new string[0], new[] { msToSend }, _tagNamespace);
}
}).Result;
faceTags = detectResult.Photos.SelectMany(i => i.Tags).ToList();
}
catch (Exception ex)
{
log.Error("Remote call", ex);
}
if (null == faceTags || faceTags.Count == 0)
{
// our fancy web service can't figure out anything, use the local library :(
finalUrl = _imageCleanupService.CleanUpImage(rawDataUrl, out intermediateUrl);
return new string[0];
}
var intermediateImage = new Bitmap(image);
var faces = faceTags.Select(i => GetTagBoundingBox(i, image)).ToList();
addedOverlay = faceTags.Select(f => ProcessFace(f, intermediateImage, image)).ToList().Any(_ => _);
var boundary = Math.Max(40, faces.Max(i => Math.Max(i.Height, i.Width)));
var x1 = Math.Max(0, faces.Min(i => i.Left) - boundary);
var y1 = Math.Max(0, faces.Min(i => i.Top) - boundary);
var x2 = Math.Min(image.Width, faces.Max(i => i.Right) + boundary);
var y2 = Math.Min(image.Height, faces.Max(i => i.Bottom) + boundary);
var newBoundingBox = new Rectangle(x1, y1, x2 - x1, y2 - y1);
new RectanglesMarker(new[] { newBoundingBox }, Color.Blue).ApplyInPlace(intermediateImage);
using (var ms2 = new MemoryStream())
{
intermediateImage.Save(ms2, ImageFormat.Jpeg);
intermediateUrl = string.Concat("data:image/jpeg;base64,", Convert.ToBase64String(ms2.ToArray()));
}
// save the original image without cropping @ JPG/100
var finalImage = ImageHelper.GetBytes(s => image.Save(s, ImageHelper.JPEGEncoder(), ImageHelper.Quality(100)));
finalUrl = string.Concat("data:image/jpeg;base64,", Convert.ToBase64String(finalImage));
return faceTags.Select(GetMatch).Where(i => i != null).ToArray();
}
}