Beispiel #1
0
        /*
         * END - GENERATE THUMBNAIL
         */

        // <snippet_read_url>

        /*
         * READ FILE - URL
         * Extracts text.
         */
        public async Task ReadFileUrl(string urlFile)
        {
            Console.WriteLine("----------------------------------------------------------");
            Console.WriteLine("READ FILE FROM URL");
            Console.WriteLine();

            // Read text from URL
            var textHeaders = await _computerVisionClient.ReadAsync(urlFile, language : "en");

            // After the request, get the operation location (operation ID)
            string operationLocation = textHeaders.OperationLocation;

            Thread.Sleep(2000);
            // </snippet_extract_call>

            // <snippet_read_response>
            // Retrieve the URI where the extracted text will be stored from the Operation-Location header.
            // We only need the ID and not the full URL
            const int numberOfCharsInOperationId = 36;
            string    operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);

            // Extract the text
            ReadOperationResult results;

            Console.WriteLine($"Extracting text from URL file {Path.GetFileName(urlFile)}...");
            Console.WriteLine();
            do
            {
                results = await _computerVisionClient.GetReadResultAsync(Guid.Parse(operationId));
            }while ((results.Status == OperationStatusCodes.Running ||
                     results.Status == OperationStatusCodes.NotStarted));
            // </snippet_read_response>

            // <snippet_read_display>
            // Display the found text.
            Console.WriteLine();
            var textUrlFileResults = results.AnalyzeResult.ReadResults;

            foreach (ReadResult page in textUrlFileResults)
            {
                foreach (Line line in page.Lines)
                {
                    Console.WriteLine(line.Text);
                }
            }
            // </snippet_read_display>
            Console.WriteLine();
        }
Beispiel #2
0
        // Receives the image path and returns the businesscard
        public override async Task <Businesscard> getCard(string imagePath)
        {
            try
            {
                using (var image = File.OpenRead(imagePath))
                {
                    Businesscard card = MakeEmptyCard();
                    Debug.WriteLine("AZUREVISION - Received image");
                    var textHeaders = await cv.ReadInStreamAsync(image);

                    string operationLocation = textHeaders.OperationLocation;
                    string operationId       = operationLocation.Substring(operationLocation.Length - 36);
                    // Extract the text
                    ReadOperationResult results = null;
                    Debug.WriteLine("AZUREVISION - sending image to Azure Service");
                    do
                    {
                        results = await cv.GetReadResultAsync(Guid.Parse(operationId));
                    }while ((results.Status == OperationStatusCodes.Running ||
                             results.Status == OperationStatusCodes.NotStarted));

                    Debug.WriteLine("AZUREVISION - received information from Azure Service");
                    card = await analyzeText(formatResults(results));

                    PrintCard(card);
                    return(card);
                }
            }
            catch (Exception ex)
            {
                throw new BadRequestException(ex.ToString());
            }
        }
Beispiel #3
0
        public async Task ReadFileLocal(ComputerVisionClient client, string imageFile)
        {
            Console.WriteLine("-----------------------------------------------");
            Console.WriteLine("Read Image from file");
            Console.WriteLine();

            var textHeaders = await client.ReadInStreamAsync(File.OpenRead(imageFile), language : "en");

            string operationLocation = textHeaders.OperationLocation;

            Thread.Sleep(2000);

            const int numberOfCharsInOperationId = 36;
            string    operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);

            ReadOperationResult results;

            Console.WriteLine($"Reading text from local file {Path.GetFileName(imageFile)}...");
            Console.WriteLine();
            do
            {
                results = await client.GetReadResultAsync(Guid.Parse(operationId));
            } while ((results.Status == OperationStatusCodes.Running || results.Status == OperationStatusCodes.NotStarted));

            SaveOutputToFile(results.AnalyzeResult.ReadResults, imageFile);
        }
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            var cv = new ComputerVisionClient(new ApiKeyServiceClientCredentials(""))
            {
                Endpoint = ""
            };

            using (var image = System.IO.File.OpenRead(@"D:\Data\inf103ss\Documents\voorbeeldkaart.jpg"))
            {
                var textHeaders = await cv.ReadInStreamAsync(image);

                string operationLocation = textHeaders.OperationLocation;
                string operationId       = operationLocation.Substring(operationLocation.Length - 36);
                // Extract the text
                ReadOperationResult results;
                do
                {
                    results = await cv.GetReadResultAsync(Guid.Parse(operationId));
                }while ((results.Status == OperationStatusCodes.Running ||
                         results.Status == OperationStatusCodes.NotStarted));

                Console.WriteLine();
                var textUrlFileResults = results.AnalyzeResult.ReadResults;
                foreach (ReadResult page in textUrlFileResults)
                {
                    foreach (Line line in page.Lines)
                    {
                        Console.WriteLine(line.Text);
                    }
                }
                Console.WriteLine();
            }
        }
Beispiel #5
0
        public List <string> ExtractOCRTextFromLocalFile(string localFile, string language = "en")
        {
            var textHeaders = _client.ReadInStreamAsync(File.OpenRead(localFile), language: language).Result;

            // After the request, get the operation location (operation ID)
            string operationLocation = textHeaders.OperationLocation;

            Thread.Sleep(2000);

            // Retrieve the URI where the recognized text will be stored from the Operation-Location header.
            // We only need the ID and not the full URL
            const int numberOfCharsInOperationId = 36;
            string    operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);

            // Extract the text
            ReadOperationResult results;

            do
            {
                results = _client.GetReadResultAsync(Guid.Parse(operationId)).Result;
            }while (results.Status == OperationStatusCodes.Running || results.Status == OperationStatusCodes.NotStarted);

            List <string> foundTextSnippets  = new List <string>();
            var           textUrlFileResults = results.AnalyzeResult.ReadResults;

            foreach (ReadResult page in textUrlFileResults)
            {
                foreach (Line line in page.Lines)
                {
                    foundTextSnippets.Add(line.Text);
                }
            }

            return(foundTextSnippets);
        }
Beispiel #6
0
        /*
         * END - GENERATE THUMBNAIL
         */

        // <snippet_extract_call>

        /*
         * BATCH READ FILE - URL IMAGE
         * Recognizes handwritten text.
         * This API call offers an improvement of results over the Recognize Text calls.
         */
        public static async Task BatchReadFileUrl(ComputerVisionClient client, string urlImage)
        {
            Console.WriteLine("----------------------------------------------------------");
            Console.WriteLine("BATCH READ FILE - URL IMAGE");
            Console.WriteLine();

            // Read text from URL
            var textHeaders = await client.ReadAsync(urlImage, language : "en");

            // After the request, get the operation location (operation ID)
            string operationLocation = textHeaders.OperationLocation;
            // </snippet_extract_call>

            // <snippet_extract_response>
            // Retrieve the URI where the recognized text will be stored from the Operation-Location header.
            // We only need the ID and not the full URL
            const int numberOfCharsInOperationId = 36;
            string    operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);

            // Extract the text
            // Delay is between iterations and tries a maximum of 10 times.
            int i          = 0;
            int maxRetries = 10;
            ReadOperationResult results;

            Console.WriteLine($"Extracting text from URL image {Path.GetFileName(urlImage)}...");
            Console.WriteLine();
            do
            {
                results = await client.GetReadResultAsync(operationId);

                Console.WriteLine("Server status: {0}, waiting {1} seconds...", results.Status, i);
                await Task.Delay(1000);

                if (i == 9)
                {
                    Console.WriteLine("Server timed out.");
                }
            }while ((results.Status == TextOperationStatusCodes.Running ||
                     results.Status == TextOperationStatusCodes.NotStarted) && i++ < maxRetries);
            // </snippet_extract_response>

            // <snippet_extract_display>
            // Display the found text.
            Console.WriteLine();
            var textRecognitionLocalFileResults = results.RecognitionResults;

            foreach (TextRecognitionResult recResult in textRecognitionLocalFileResults)
            {
                foreach (Line line in recResult.Lines)
                {
                    Console.WriteLine(line.Text);
                }
            }
            Console.WriteLine();
        }
Beispiel #7
0
        public override async Task RunCommand(object sender)
        {
            var engine  = (IAutomationEngineInstance)sender;
            var vAPIKey = (string)await v_APIKey.EvaluateCode(engine);

            var vEndpoint = (string)await v_Endpoint.EvaluateCode(engine);

            Stream imageStream = null;

            if (v_ImageType == "Filepath")
            {
                imageStream = new FileStream((string)await v_FilePath.EvaluateCode(engine), FileMode.Open);
            }
            else
            {
                Bitmap vBitmap = (Bitmap)await v_Bitmap.EvaluateCode(engine);

                imageStream = new FileStream(engine.EngineContext.ProjectPath + "\\tempOCRBitmap.bmp", FileMode.OpenOrCreate);
                vBitmap.Save(imageStream, ImageFormat.Bmp);
                imageStream.Close();
                imageStream = new FileStream(engine.EngineContext.ProjectPath + "\\tempOCRBitmap.bmp", FileMode.Open);
            }
            ComputerVisionClient client =
                new ComputerVisionClient(new ApiKeyServiceClientCredentials(vAPIKey))
            {
                Endpoint = vEndpoint
            };
            var textHeaders = await client.ReadInStreamAsync(imageStream);

            string operationLocation = textHeaders.OperationLocation;

            Thread.Sleep(2000);

            const int numberOfCharsInOperationId = 36;
            string    operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);

            ReadOperationResult results;

            do
            {
                results = await client.GetReadResultAsync(Guid.Parse(operationId));
            }while ((results.Status == OperationStatusCodes.Running ||
                     results.Status == OperationStatusCodes.NotStarted));
            string readText           = "";
            var    textUrlFileResults = results.AnalyzeResult.ReadResults;

            foreach (ReadResult page in textUrlFileResults)
            {
                foreach (Line line in page.Lines)
                {
                    readText += line.Text + "\n";
                }
            }
            readText.SetVariableValue(engine, v_OutputUserVariableName);
        }
        internal static async Task <ReadOperationResult> GetReadOperationResult(ComputerVisionClient client, string operationId)
        {
            ReadOperationResult results;

            do
            {
                results = await client.GetReadResultAsync(Guid.Parse(operationId));
            }while ((results.Status == OperationStatusCodes.Running ||
                     results.Status == OperationStatusCodes.NotStarted));

            return(results);
        }
Beispiel #9
0
        /// <summary>
        /// Sends an image to the Azure Cognitive Vision and returns the rendered text.
        /// More information available at https://westcentralus.dev.cognitive.microsoft.com/docs/services/computer-vision-v3-1-ga/operations/5d986960601faab4bf452005
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public async Task <List <DocumentText> > ReadImage(Stream stream)
        {
            try
            {
                var streamHeaders = await ComputerVisionClient.ReadInStreamAsync(stream, "en");

                var operationLocation = streamHeaders.OperationLocation;

                const int numberOfCharsInOperationId = 36;
                string    operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);

                await Task.Delay(1000);

                ReadOperationResult readOperationResult;
                do
                {
                    readOperationResult = await ComputerVisionClient.GetReadResultAsync(Guid.Parse(operationId));
                } while (readOperationResult.Status == OperationStatusCodes.Running ||
                         readOperationResult.Status == OperationStatusCodes.NotStarted);

                var listOfDocumentText = new List <DocumentText>();

                var arrayOfReadResults = readOperationResult.AnalyzeResult.ReadResults;
                foreach (var page in arrayOfReadResults)
                {
                    foreach (var line in page.Lines)
                    {
                        var boundBox = new BoundingBox()
                        {
                            Left   = line.BoundingBox[0],
                            Top    = line.BoundingBox[1],
                            Right  = line.BoundingBox[4],
                            Bottom = line.BoundingBox[5]
                        };

                        var documentText = new DocumentText()
                        {
                            BoundingBox = boundBox,
                            Text        = line.Text
                        };

                        listOfDocumentText.Add(documentText);
                    }
                }

                return(listOfDocumentText);
            }
            catch (Exception e)
            {
                Logger.LogError(e, $"failed to analyze file");
                return(null);
            }
        }
Beispiel #10
0
        private async Task <IList <Line> > ExtractLinesFromImage(string filePath, string writeToJsonPath = null)
        {
            IList <ReadResult> textResults;

            if (filePath.EndsWith("json"))
            {
                using (StreamReader r = new StreamReader(filePath))
                {
                    string json = r.ReadToEnd();
                    textResults = JsonConvert.DeserializeObject <IList <ReadResult> >(json);
                }
            }
            else
            {
                ReadInStreamHeaders textHeaders;
                try
                {
                    textHeaders = await _client.ReadInStreamAsync(File.OpenRead(filePath), language : "en");
                } catch (Exception ex)
                {
                    Log.Error(ex, "Error using Azure's ReadInStreamAsync method");
                    return(null);
                }
                string operationLocation = textHeaders.OperationLocation;
                //Thread.Sleep(2000); // This is in the github examples

                // Retrieve the URI where the recognized text will be stored from the Operation-Location header.
                // We only need the ID and not the full URL
                const int numberOfCharsInOperationId = 36;
                string    operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);

                ReadOperationResult results;
                do
                {
                    results = await _client.GetReadResultAsync(Guid.Parse(operationId));
                }while ((results.Status == OperationStatusCodes.Running ||
                         results.Status == OperationStatusCodes.NotStarted));

                textResults = results.AnalyzeResult.ReadResults;

                if (writeToJsonPath != null)
                {
                    string json = JsonConvert.SerializeObject(textResults, Formatting.Indented);
                    System.IO.File.WriteAllText(writeToJsonPath, json);
                }
            }

            return(textResults[0].Lines);
        }
        private async Task <ReadOperationResult> GetReadOperationResultAsync(string operationLocation)
        {
            var operationId = new Guid(operationLocation.Substring(operationLocation.Length - _computerVisionOperationIdLength));
            var result      = await _computerVisionClient.GetReadResultAsync(operationId);

            // Wait for the operation to complete
            int i = 1;
            int waitDurationInMs = 500;
            var maxWaitTimeInMs  = 30000;
            int maxTries         = maxWaitTimeInMs / waitDurationInMs;

            while ((result.Status == OperationStatusCodes.Running || result.Status == OperationStatusCodes.NotStarted) &&
                   i <= maxTries)
            {
                Console.WriteLine($"Computer Vision Read - Server status: {0}, try {1}, waiting {2} milliseconds...", result.Status, i, waitDurationInMs);
                await Task.Delay(waitDurationInMs);

                result = await _computerVisionClient.GetReadResultAsync(operationId);

                i++;
            }

            return(result);
        }
        public async Task <ReadOperationResult> ParseFileInternal(Stream file)
        {
            var response = await _client.ReadInStreamAsync(file);

            const int NumberOfCharsInOperationId = 36;
            string    operationId = response.OperationLocation.Substring(response.OperationLocation.Length - NumberOfCharsInOperationId);

            ReadOperationResult result;

            do
            {
                result = await _client.GetReadResultAsync(Guid.Parse(operationId));
            }while (result.Status == OperationStatusCodes.Running || result.Status == OperationStatusCodes.NotStarted);
            return(result);
        }
        // </snippet_readfileurl_3>

        /*
         * END - READ FILE - URL
         */


        // <snippet_read_local>

        /*
         * READ FILE - LOCAL
         */

        public static async Task ReadFileLocal(ComputerVisionClient client, string localFile)
        {
            Console.WriteLine("----------------------------------------------------------");
            Console.WriteLine("READ FILE FROM LOCAL");
            Console.WriteLine();

            // Read text from URL

            // language code = null, pages = null, and specify model-version.
            var textHeaders = await client.ReadInStreamAsync(File.OpenRead(localFile), null, null, "2022-01-30-preview");

            // After the request, get the operation location (operation ID)
            string operationLocation = textHeaders.OperationLocation;

            Thread.Sleep(2000);

            // <snippet_extract_response>
            // Retrieve the URI where the recognized text will be stored from the Operation-Location header.
            // We only need the ID and not the full URL
            const int numberOfCharsInOperationId = 36;
            string    operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);

            // Extract the text
            ReadOperationResult results;

            Console.WriteLine($"Reading text from local file {Path.GetFileName(localFile)}...");
            Console.WriteLine();
            do
            {
                results = await client.GetReadResultAsync(Guid.Parse(operationId));
            }while ((results.Status == OperationStatusCodes.Running ||
                     results.Status == OperationStatusCodes.NotStarted));
            // </snippet_extract_response>

            // <snippet_extract_display>
            // Display the found text.
            Console.WriteLine();
            var textUrlFileResults = results.AnalyzeResult.ReadResults;

            foreach (ReadResult page in textUrlFileResults)
            {
                foreach (Line line in page.Lines)
                {
                    Console.WriteLine(line.Text);
                }
            }
            Console.WriteLine();
        }
Beispiel #14
0
        private async static void getTexto(ComputerVisionClient cliente, string url)
        {
            var streamImg = new FileStream(url, FileMode.Open, FileAccess.Read, FileShare.Read);

            var text = await cliente.ReadInStreamAsync(streamImg, language : "es");

            var operacion = text.OperationLocation;

            Thread.Sleep(2000);

            const int numero = 36;

            Console.WriteLine("Operation Location");
            Console.WriteLine(operacion.Substring(operacion.Length - numero));
            var operationId = operacion.Substring(operacion.Length - numero);

            //extraer el texto
            ReadOperationResult results;

            Console.WriteLine("Extrayendo de url: ");
            Console.WriteLine();

            do
            {
                results = await cliente.GetReadResultAsync(Guid.Parse(operationId));
            } while ((results.Status == OperationStatusCodes.Running) || (results.Status == OperationStatusCodes.NotStarted));

            //Deplegando texto encontrado en imagen

            Console.WriteLine();
            var textUrl = results.AnalyzeResult.ReadResults;

            foreach (var res in textUrl)
            {
                foreach (var linea in res.Lines)
                {
                    Console.WriteLine(linea.Text);
                }
            }
            Console.WriteLine();
        }
        static async Task Main(string[] args)
        {
            const string SUBSCRIPTION_KEY = "PONER AQUI LA CLAVE";
            const string ENDPOINT         = "PONER AQUI LA URL DEL ENDPOINT";
            const string IMAGE_BASE_URL   = "https://moderatorsampleimages.blob.core.windows.net/samples";

            ComputerVisionClient client = new ComputerVisionClient(new ApiKeyServiceClientCredentials(SUBSCRIPTION_KEY))
            {
                Endpoint = ENDPOINT
            };

            /////////////////////////
            //Análisis de imagen (ComputerVision-Analyze Image)
            /////////////////////////
            Console.WriteLine("---Análisis de imagen---");

            //Definimos la lista de características y detalles que queremos obtener de la imagen
            List <VisualFeatureTypes?> caracteristicas = new List <VisualFeatureTypes?>()
            {
                VisualFeatureTypes.Categories, VisualFeatureTypes.Description,
                VisualFeatureTypes.Tags, VisualFeatureTypes.Adult,
                VisualFeatureTypes.Objects
            };

            List <Details?> detalles = new List <Details?>()
            {
                Details.Celebrities
            };

            //Invocamos el método de la API para el análisis de la imagen
            ImageAnalysis resultado = await client.AnalyzeImageAsync(
                url : $"{IMAGE_BASE_URL}/sample1.jpg",
                visualFeatures : caracteristicas,
                details : detalles,
                language : "es"
                );

            //Procesamos el resultado
            //Descripción
            Console.WriteLine($"Descripción:{resultado.Description.Captions[0].Text}");

            //Categorías
            Console.WriteLine("Categorías:");
            foreach (Category categoria in resultado.Categories)
            {
                Console.WriteLine($"\t{categoria.Name} ({categoria.Score})");
            }
            ;

            //Etiquetas
            Console.WriteLine("Etiquetas:");
            foreach (ImageTag etiqueta in resultado.Tags)
            {
                Console.WriteLine($"\t{etiqueta.Name} ({etiqueta.Confidence})");
            }
            ;

            //Contenido para adultos
            Console.WriteLine($"¿Contenido para adultos? {resultado.Adult.IsAdultContent}");
            Console.WriteLine($"¿Contenido subido de tono? {resultado.Adult.IsRacyContent}");
            Console.WriteLine($"¿Contenido sangriento? {resultado.Adult.IsGoryContent}");

            //Objetos encontrados
            Console.WriteLine("Objetos:");
            foreach (DetectedObject objeto in resultado.Objects)
            {
                Console.WriteLine($"\t{objeto.ObjectProperty} ({objeto.Rectangle.W},{objeto.Rectangle.H},{objeto.Rectangle.X},{objeto.Rectangle.Y})");
            }
            ;

            //Famosos
            Console.WriteLine("Famosos:");
            foreach (Category categoria in resultado.Categories)
            {
                if (categoria.Detail?.Celebrities != null)
                {
                    foreach (CelebritiesModel famoso in categoria.Detail.Celebrities)
                    {
                        Console.WriteLine($"\t{famoso.Name}");
                    }
                }
            }

            /////////////////////////
            //Obtención de miniatura (ComputerVision-Get Thumbnail)
            /////////////////////////
            Console.WriteLine("---Obtención de miniatura---");

            //Invocamos el método de la API para obtener la miniatura
            Stream miniatura = await client.GenerateThumbnailAsync(100, 100, $"{IMAGE_BASE_URL}/sample6.png", true);

            //Almacenamos el stream del resultado en un fichero local
            using (Stream file = File.Create("./miniatura.jpg")) { miniatura.CopyTo(file); }
            Console.WriteLine($"Generado el fichero miniatura.jpg");

            /////////////////////////
            //OCR (ComputerVision-Read)
            /////////////////////////
            Console.WriteLine("---OCR---");

            //Invocamos el método de la API para solicitar la operación de lectura
            ReadHeaders operacionOCR = await client.ReadAsync($"{IMAGE_BASE_URL}/sample2.jpg", language : "es");

            //Obtenemos el identificador de la operaciónd e lectura
            string localizador = operacionOCR.OperationLocation;
            string idOperacion = localizador.Substring(localizador.Length - 36);

            //Esperamos a que la operación de lectura acabe
            ReadOperationResult resultadoOCR;

            while (true)
            {
                await Task.Delay(1000);

                resultadoOCR = await client.GetReadResultAsync(Guid.Parse(idOperacion));

                if (resultadoOCR.Status == OperationStatusCodes.Succeeded)
                {
                    break;
                }
            }

            //Procesamos el resultado
            Console.WriteLine("Texto encontrado:");
            foreach (ReadResult pagina in resultadoOCR.AnalyzeResult.ReadResults)
            {
                foreach (Line linea in pagina.Lines)
                {
                    Console.WriteLine($"\t{linea.Text}");
                }
            }
        }
        public async Task <List <DocumentText> > ReadImage(string filename)
        {
            try
            {
                using (var fileStream = File.OpenRead(filename))
                {
                    var streamHeaders = await ComputerVisionClient.ReadInStreamAsync(fileStream, "en");

                    var operationLocation = streamHeaders.OperationLocation;

                    const int numberOfCharsInOperationId = 36;
                    string    operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);

                    await Task.Delay(1500);

                    ReadOperationResult readOperationResult;
                    do
                    {
                        readOperationResult = await ComputerVisionClient.GetReadResultAsync(Guid.Parse(operationId));
                    } while (readOperationResult.Status == OperationStatusCodes.Running ||
                             readOperationResult.Status == OperationStatusCodes.NotStarted);

                    var listOfDocumentText = new List <DocumentText>();

                    var arrayOfReadResults = readOperationResult.AnalyzeResult.ReadResults;
                    foreach (var page in arrayOfReadResults)
                    {
                        foreach (var line in page.Lines)
                        {
                            var boundBox = new BoundingBox()
                            {
                                x1 = line.BoundingBox[0],
                                y1 = line.BoundingBox[1],
                                x2 = line.BoundingBox[2],
                                y2 = line.BoundingBox[3]
                            };

                            var documentText = new DocumentText()
                            {
                                BoundingBox = boundBox,
                                Text        = line.Text
                            };

                            listOfDocumentText.Add(documentText);
                        }
                    }

                    return(listOfDocumentText);
                }
            }
            catch (FileNotFoundException e)
            {
                Logger.LogInformation($"file not found: {filename}");
                throw e;
            }
            catch (Exception e)
            {
                Logger.LogError(e, $"failed to analyze file: {filename}");
                return(null);
            }
        }