using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; using System.Windows.Forms; using System.IO; using System.Text.Json; namespace Test_Merge { public class Reader { const int NUMBER_OF_DRIVERS = 20; public List Drivers; public List MainZones; public Reader(string configFile, Bitmap image,bool loadOCR = true) { MainZones = Load(image,configFile,ref Drivers,loadOCR); } /// /// Method that reads the JSON config file and create all the Zones and Windows /// /// The image #id on wich you want to create the zones on public static List Load(Bitmap image,string configFilePath,ref List driverListToFill,bool LoadOCR) { List mainZones = new List(); Bitmap fullImage = image; List drivers; Zone mainZone; try { using (var streamReader = new StreamReader(configFilePath)) { var jsonText = streamReader.ReadToEnd(); var jsonDocument = JsonDocument.Parse(jsonText); var driversNames = jsonDocument.RootElement.GetProperty("Drivers"); driverListToFill = new List(); foreach (var nameElement in driversNames.EnumerateArray()) { driverListToFill.Add(nameElement.GetString()); } var mainProperty = jsonDocument.RootElement.GetProperty("Main"); Point MainPosition = new Point(mainProperty.GetProperty("x").GetInt32(), mainProperty.GetProperty("y").GetInt32()); Size MainSize = new Size(mainProperty.GetProperty("width").GetInt32(), mainProperty.GetProperty("height").GetInt32()); Rectangle MainRectangle = new Rectangle(MainPosition, MainSize); mainZone = new Zone(image, MainRectangle,"Main"); var zones = mainProperty.GetProperty("Zones"); var driverZone = zones[0].GetProperty("DriverZone"); Point FirstZonePosition = new Point(driverZone.GetProperty("x").GetInt32(), driverZone.GetProperty("y").GetInt32()); Size FirstZoneSize = new Size(driverZone.GetProperty("width").GetInt32(), driverZone.GetProperty("height").GetInt32()); var windows = driverZone.GetProperty("Windows"); var driverPosition = windows[0].GetProperty("Position"); Size driverPositionArea = new Size(driverPosition.GetProperty("width").GetInt32(), FirstZoneSize.Height); Point driverPositionPosition = new Point(driverPosition.GetProperty("x").GetInt32(), driverPosition.GetProperty("y").GetInt32()); var driverGapToLeader = windows[0].GetProperty("GapToLeader"); Size driverGapToLeaderArea = new Size(driverGapToLeader.GetProperty("width").GetInt32(), FirstZoneSize.Height); Point driverGapToLeaderPosition = new Point(driverGapToLeader.GetProperty("x").GetInt32(), driverGapToLeader.GetProperty("y").GetInt32()); var driverLapTime = windows[0].GetProperty("LapTime"); Size driverLapTimeArea = new Size(driverLapTime.GetProperty("width").GetInt32(), FirstZoneSize.Height); Point driverLapTimePosition = new Point(driverLapTime.GetProperty("x").GetInt32(), driverLapTime.GetProperty("y").GetInt32()); var driverDrs = windows[0].GetProperty("DRS"); Size driverDrsArea = new Size(driverDrs.GetProperty("width").GetInt32(), FirstZoneSize.Height); Point driverDrsPosition = new Point(driverDrs.GetProperty("x").GetInt32(), driverDrs.GetProperty("y").GetInt32()); var driverTyres = windows[0].GetProperty("Tyres"); Size driverTyresArea = new Size(driverTyres.GetProperty("width").GetInt32(), FirstZoneSize.Height); Point driverTyresPosition = new Point(driverTyres.GetProperty("x").GetInt32(), driverTyres.GetProperty("y").GetInt32()); var driverName = windows[0].GetProperty("Name"); Size driverNameArea = new Size(driverName.GetProperty("width").GetInt32(), FirstZoneSize.Height); Point driverNamePosition = new Point(driverName.GetProperty("x").GetInt32(), driverName.GetProperty("y").GetInt32()); var driverSector1 = windows[0].GetProperty("Sector1"); Size driverSector1Area = new Size(driverSector1.GetProperty("width").GetInt32(), FirstZoneSize.Height); Point driverSector1Position = new Point(driverSector1.GetProperty("x").GetInt32(), driverSector1.GetProperty("y").GetInt32()); var driverSector2 = windows[0].GetProperty("Sector2"); Size driverSector2Area = new Size(driverSector2.GetProperty("width").GetInt32(), FirstZoneSize.Height); Point driverSector2Position = new Point(driverSector2.GetProperty("x").GetInt32(), driverSector2.GetProperty("y").GetInt32()); var driverSector3 = windows[0].GetProperty("Sector3"); Size driverSector3Area = new Size(driverSector3.GetProperty("width").GetInt32(), FirstZoneSize.Height); Point driverSector3Position = new Point(driverSector3.GetProperty("x").GetInt32(), driverSector3.GetProperty("y").GetInt32()); float offset = (((float)mainZone.ZoneImage.Height - (float)(driverListToFill.Count * FirstZoneSize.Height)) / (float)driverListToFill.Count); Bitmap MainZoneImage = mainZone.ZoneImage; List zonesToAdd = new List(); List zonesImages = new List(); for (int i = 0; i < NUMBER_OF_DRIVERS; i++) { Point tmpPos = new Point(0, FirstZonePosition.Y + i * FirstZoneSize.Height - Convert.ToInt32(i * offset)); Zone newDriverZone = new Zone(MainZoneImage, new Rectangle(tmpPos, FirstZoneSize), "DriverZone"); zonesToAdd.Add(newDriverZone); zonesImages.Add(newDriverZone.ZoneImage); newDriverZone.ZoneImage.Save("Driver"+i+".png"); } //Parallel.For(0, NUMBER_OF_DRIVERS, i => for (int i = 0; i < NUMBER_OF_DRIVERS; i++) { Zone newDriverZone = zonesToAdd[(int)i]; Bitmap zoneImg = zonesImages[(int)i]; newDriverZone.AddWindow(new DriverPositionWindow(zoneImg, new Rectangle(driverPositionPosition, driverPositionArea),LoadOCR)); newDriverZone.AddWindow(new DriverGapToLeaderWindow(zoneImg, new Rectangle(driverGapToLeaderPosition, driverGapToLeaderArea), LoadOCR)); newDriverZone.AddWindow(new DriverLapTimeWindow(zoneImg, new Rectangle(driverLapTimePosition, driverLapTimeArea), LoadOCR)); newDriverZone.AddWindow(new DriverDrsWindow(zoneImg, new Rectangle(driverDrsPosition, driverDrsArea), LoadOCR)); newDriverZone.AddWindow(new DriverTyresWindow(zoneImg, new Rectangle(driverTyresPosition, driverTyresArea), LoadOCR)); newDriverZone.AddWindow(new DriverNameWindow(zoneImg, new Rectangle(driverNamePosition, driverNameArea), LoadOCR)); newDriverZone.AddWindow(new DriverSectorWindow(zoneImg, new Rectangle(driverSector1Position, driverSector1Area),1, LoadOCR)); newDriverZone.AddWindow(new DriverSectorWindow(zoneImg, new Rectangle(driverSector2Position, driverSector2Area),2, LoadOCR)); newDriverZone.AddWindow(new DriverSectorWindow(zoneImg, new Rectangle(driverSector3Position, driverSector3Area),3, LoadOCR)); mainZone.AddZone(newDriverZone); }//); //MessageBox.Show("We have a main zone with " + MainZone.Zones.Count() + " Driver zones with " + MainZone.Zones[4].Windows.Count() + " windows each and we have " + Drivers.Count + " drivers"); mainZones.Add(mainZone); } } catch (IOException ex) { MessageBox.Show("Error reading JSON file: " + ex.Message); } catch (JsonException ex) { MessageBox.Show("Invalid JSON format: " + ex.Message); } return mainZones; } /// /// Method that calls all the zones and windows to get the content they can find on the image to display them /// /// The id of the image we are working with /// a string representation of all the returns public async Task Decode(List mainZones,List drivers) { string result = ""; List mainResults = new List(); //Decode for (int mainZoneId = 0; mainZoneId < mainZones.Count; mainZoneId++) { switch (mainZoneId) { case 0: //Main Zone foreach (Zone z in mainZones[mainZoneId].Zones) { mainResults.Add(await z.Decode(Drivers)); } break; //Next there could be a Title Zone and TrackInfoZone } } //Display foreach (DriverData driver in mainResults) { result += driver.ToString(); result += Environment.NewLine; } return result; } /// /// Method that can be used to convert an amount of miliseconds into a more readable human form /// /// The given amount of miliseconds ton convert /// A human readable string that represents the ms public static string ConvertMsToTime(int amountOfMs) { //Convert.ToInt32 would round upand I dont want that int minuts = (int)((float)amountOfMs / (1000f * 60f)); int seconds = (int)((amountOfMs - (minuts * 60f * 1000f)) / 1000); int ms = amountOfMs - ((minuts * 60 * 1000) + (seconds * 1000)); return minuts + ":" + seconds.ToString("00") + ":" + ms.ToString("000"); } /// /// Old method that can draw on an image where the windows and zones are created. mostly used for debugging /// /// the #id of the image we are working with /// the drawed bitmap public Bitmap Draw(Bitmap image,List mainZones) { Graphics g = Graphics.FromImage(image); foreach (Zone z in mainZones) { int count = 0; foreach (Zone zz in z.Zones) { g.DrawRectangle(Pens.Red, z.Bounds); foreach (Window w in zz.Windows) { g.DrawRectangle(Pens.Blue, new Rectangle(z.Bounds.X + zz.Bounds.X, z.Bounds.Y + zz.Bounds.Y, zz.Bounds.Width, zz.Bounds.Height)); } count++; } } return image; } } }