public static HttpResponseMessage RequestImageProcessing(
            [HttpTrigger(AuthorizationLevel.Anonymous, new string[] { "POST" })] MosaicRequest input,
            [Queue("%generate-mosaic%")] out MosaicRequest queueOutput,
            TraceWriter log)
        {
            if (string.IsNullOrEmpty(input.OutputFilename))
            {
                input.OutputFilename = $"{Guid.NewGuid()}.jpg";
            }

            queueOutput = input;

            // get output URL
            var storageURL          = Environment.GetEnvironmentVariable("STORAGE_URL");
            var outputContainerName = Environment.GetEnvironmentVariable("output-container");
            var location            = $"{storageURL}{outputContainerName}/{input.OutputFilename}";

            log.Info($"\n\nOutput location:\n{location}\n\n");

            var response = new HttpResponseMessage(HttpStatusCode.Accepted);

            response.Content          = new StringContent(location);
            response.Headers.Location = new Uri(location);

            return(response);
        }
Example #2
0
        public static async Task CreateMosaicAsync(
            [QueueTrigger("generate-mosaic")] MosaicRequest mosaicRequest,
            [Blob("%input-container%/{InputImage}", FileAccess.Read)] Stream sourceImage,
            [Blob("%tile-image-container%")] CloudBlobContainer tileContainer,
            [Blob("%output-container%/{InputImage}", FileAccess.Write)] Stream outputStream,
            TraceWriter log)
        {
            var query = "";

            // TODO: if confidence is too low, fall back to vision API

            try {
                query = await PredictImageAsync(sourceImage);
            }
            catch (Exception e) {
                log.Info($"Custom image failed, trying vision API: {e.Message}");
                query = await AnalyzeImageAsync(sourceImage);
            }

            log.Info($"Image analysis: {query}");

            var queryDirectory = Utilities.GetStableHash(query).ToString();

            log.Info($"Query hash: {queryDirectory}");

            var imageUrls = await DownloadImages.GetImageResultsAsync(query, log);

            await DownloadImages.DownloadImagesAsync(queryDirectory, imageUrls, tileContainer);

            GenerateMosaicFromTiles(sourceImage, tileContainer, queryDirectory, outputStream);
        }
Example #3
0
        public static async Task CreateMosaicAsync(
            [QueueTrigger("generate-mosaic")] MosaicRequest mosaicRequest,
            [Blob("%input-container%/{InputImage}", FileAccess.Read)] Stream sourceImage,
            [Blob("%tile-image-container%")] CloudBlobContainer tileContainer,
            [Blob("%output-container%/{InputImage}", FileAccess.Write)] Stream outputStream,
            TraceWriter log)
        {
            var imageKeyword = mosaicRequest.ImageContentString;

            if (String.IsNullOrEmpty(mosaicRequest.ImageContentString))   // no keyword provided, use image recognition

            // fall back to regular vision service if PredictionApiUrl is empty,
            // or if Custom Vision does not have high confidence
            {
                bool   useFallback   = false;
                string predictionUrl = Environment.GetEnvironmentVariable("PredictionApiUrl");

                if (String.IsNullOrEmpty(predictionUrl))   // if no Custom Vision API key was provided, skip it
                {
                    useFallback = true;
                }

                try {
                    imageKeyword = await PredictImageAsync(predictionUrl, sourceImage, log);

                    useFallback = String.IsNullOrEmpty(imageKeyword);
                }
                catch (Exception e) {
                    log.Info($"Custom image failed: {e.Message}");
                    useFallback = true; // on exception, use regular Vision Service
                }

                if (useFallback)
                {
                    log.Info("Falling back to Vision Service");

                    sourceImage.Seek(0, SeekOrigin.Begin);
                    imageKeyword = await AnalyzeImageAsync(sourceImage);
                }
            }

            log.Info($"Image analysis: {imageKeyword}");

            var queryDirectory = Utilities.GetStableHash(imageKeyword).ToString();

            log.Info($"Query hash: {queryDirectory}");

            var imageUrls = await DownloadImages.GetImageResultsAsync(imageKeyword, log);

            await DownloadImages.DownloadImagesAsync(queryDirectory, imageUrls, tileContainer);

            GenerateMosaicFromTiles(sourceImage, tileContainer, queryDirectory, outputStream);
        }
Example #4
0
 public static MosaicRequest RequestImageProcessing(
     [HttpTrigger(AuthorizationLevel.Anonymous, new string[] { "POST" })] MosaicRequest input,
     TraceWriter log)
 {
     return(input);
 }
        public static async Task CreateMosaicAsync(
            [QueueTrigger("%generate-mosaic%")] MosaicRequest mosaicRequest,
            [Blob("%tile-image-container%")] CloudBlobContainer tileContainer,
            [Blob("%output-container%/{OutputFilename}", FileAccess.Write)] Stream outputStream,
            TraceWriter log)
        {
            var imageKeyword = mosaicRequest.ImageContentString;
            var sourceImage  = await DownloadFileAsync(mosaicRequest.InputImageUrl);

            // fall back to regular vision service if PredictionApiUrl is empty,
            // or if Custom Vision does not have high confidence
            bool noCustomImageSearch = false;

            if (String.IsNullOrEmpty(mosaicRequest.ImageContentString))   // no keyword provided, use image recognition

            {
                string predictionUrl = Environment.GetEnvironmentVariable("PredictionApiUrl");

                if (String.IsNullOrEmpty(predictionUrl))   // if no Custom Vision API key was provided, skip it
                {
                    noCustomImageSearch = true;
                }

                try {
                    imageKeyword = await PredictImageAsync(predictionUrl, sourceImage, log);

                    noCustomImageSearch = String.IsNullOrEmpty(imageKeyword);
                }
                catch (Exception e) {
                    log.Info($"Custom image failed: {e.Message}");
                    noCustomImageSearch = true; // on exception, use regular Vision Service
                }

                if (noCustomImageSearch)
                {
                    log.Info("Falling back to Vision Service");

                    sourceImage.Seek(0, SeekOrigin.Begin);
                    imageKeyword = await AnalyzeImageAsync(sourceImage);
                }
            }
            else
            {
                if (imageKeyword.EndsWith(" "))
                {
                    imageKeyword = imageKeyword.Substring(0, imageKeyword.IndexOf(" "));
                }
            }

            log.Info($"\n\nImage analysis: {imageKeyword}\n");

            var queryDirectory = Utilities.GetStableHash(imageKeyword).ToString();

            log.Info($"Query hash: {queryDirectory}");

            var imageUrls = await DownloadImages.GetImageResultsAsync(imageKeyword, log);

            await DownloadImages.GetBingImagesAsync(
                queryDirectory, imageUrls, tileContainer, TileWidth, TileHeight);

            await GenerateMosaicFromTilesAsync(
                sourceImage, tileContainer, queryDirectory,
                outputStream,
                mosaicRequest.TilePixels,
                log);

            Utilities.EmitCustomTelemetry(!noCustomImageSearch, imageKeyword);
        }