private static List <SubStat> ScanArtifactSubStats(Bitmap artifactImage, ref string setName) { Bitmap bm = (Bitmap)artifactImage.Clone(); Scraper.SetBrightness(-30, ref bm); Scraper.SetContrast(85, ref bm); var n = Scraper.ConvertToGrayscale(bm); var text = Scraper.AnalyzeText(n, Tesseract.PageSegMode.Auto).ToLower(); List <string> lines = new List <string>(text.Split('\n')); lines.RemoveAll(line => string.IsNullOrWhiteSpace(line)); var index = lines.FindIndex(line => line.Contains("piece") || line.Contains("set") || line.Contains("2-")); if (index >= 0) { lines.RemoveRange(index, lines.Count - index); } n.Dispose(); bm.Dispose(); SubStat[] substats = new SubStat[4]; List <Task <string> > tasks = new List <Task <string> >(); for (int i = 0; i < lines.Count; i++) { int j = i; var task = Task.Factory.StartNew(() => { var line = Regex.Replace(lines[j], @"(?:^[^a-zA-Z]*)", string.Empty).Replace(" ", string.Empty); if (line.Any(char.IsDigit)) { SubStat substat = new SubStat(); Regex re = new Regex(@"([\w]+\W*)(\d+.*\d+)"); var result = re.Match(line); var stat = Regex.Replace(result.Groups[1].Value, @"[^\w]", string.Empty); var value = result.Groups[2].Value; string name = line.Contains("%") ? stat + "%" : stat; substat.stat = Scraper.FindClosestStat(name) ?? ""; // Remove any non digits. value = Regex.Replace(value, @"[^0-9]", string.Empty); var cultureInfo = new CultureInfo("en-US"); if (!decimal.TryParse(value, NumberStyles.Number, cultureInfo, out substat.value)) { substat.value = -1; } // Need to retain the decimal place for percent boosts if (substat.stat.Contains("_")) { substat.value /= 10; } substats[j] = substat; return(null); } else // if (line.Contains(":")) // Sometimes Tesseract wouldn't detect a ':' making this check troublesome { var name = line.Trim().ToLower(); name = Regex.Replace(name, @"[^\w]", string.Empty); name = Scraper.FindClosestSetName(name); return(!string.IsNullOrWhiteSpace(name) ? name : null); } }); tasks.Add(task); } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (tasks.Count > 0 && stopwatch.Elapsed.TotalSeconds < 10) { for (int i = 0; i < tasks.Count; i++) { Task <string> task = tasks[i]; if (!task.IsCompleted) { continue; } setName = string.IsNullOrWhiteSpace(setName) ? task.Result : setName; tasks.Remove(task); break; } } return(substats.ToList()); }