136 lines
5.9 KiB
C#
136 lines
5.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Drawing;
|
|
|
|
namespace Test_Merge
|
|
{
|
|
public class DriverTyresWindow:Window
|
|
{
|
|
private static Random rnd = new Random();
|
|
int seed = rnd.Next(0, 10000);
|
|
|
|
//Those are the colors I found but you can change them if they change in the future like in 2019
|
|
public static Color SOFT_TYRE_COLOR = Color.FromArgb(0xff, 0x00, 0x00);
|
|
public static Color MEDIUM_TYRE_COLOR = Color.FromArgb(0xf5, 0xbf, 0x00);
|
|
public static Color HARD_TYRE_COLOR = Color.FromArgb(0xa4, 0xa5, 0xa8);
|
|
public static Color INTER_TYRE_COLOR = Color.FromArgb(0x00, 0xa4, 0x2e);
|
|
public static Color WET_TYRE_COLOR = Color.FromArgb(0x27, 0x60, 0xa6);
|
|
public static Color EMPTY_COLOR = Color.FromArgb(0x20, 0x20, 0x20);
|
|
|
|
public DriverTyresWindow(Bitmap image, Rectangle bounds, bool generateEngine = true) : base(image, bounds,generateEngine)
|
|
{
|
|
Name = "Tyres";
|
|
}
|
|
/// <summary>
|
|
/// This will decode the content of the image
|
|
/// </summary>
|
|
/// <returns>And object containing what was on the image</returns>
|
|
public override async Task<object> DecodePng()
|
|
{
|
|
return await GetTyreInfos();
|
|
}
|
|
/// <summary>
|
|
/// Method that will decode whats on the image and return the tyre infos it could manage to recover
|
|
/// </summary>
|
|
/// <returns>A tyre object containing tyre infos</returns>
|
|
private async Task<Tyre> GetTyreInfos()
|
|
{
|
|
Bitmap tyreZone = GetSmallBitmapFromBigOne(WindowImage, FindTyreZone());
|
|
Tyre.Type type = Tyre.Type.Undefined;
|
|
type = GetTyreTypeFromColor(OcrImage.GetAvgColorFromBitmap(tyreZone));
|
|
int laps = -1;
|
|
|
|
string number = await GetStringFromPng(tyreZone, Engine, "0123456789", OcrImage.WindowType.Tyre);
|
|
try
|
|
{
|
|
laps = Convert.ToInt32(number);
|
|
}
|
|
catch
|
|
{
|
|
//We could not convert the number so its a letter so its 0 laps old
|
|
laps = 0;
|
|
}
|
|
//tyreZone.Save(Reader.DEBUG_DUMP_FOLDER + "Tyre" + type + "Laps" + laps + '#' + rnd.Next(0, 1000) + ".png");
|
|
return new Tyre(type, laps);
|
|
}
|
|
/// <summary>
|
|
/// Finds where the important part of the image is
|
|
/// </summary>
|
|
/// <returns>A rectangle containing position and dimensions of the important part of the image</returns>
|
|
private Rectangle FindTyreZone()
|
|
{
|
|
Bitmap bmp = WindowImage;
|
|
int currentPosition = bmp.Width;
|
|
int height = bmp.Height / 2;
|
|
Color limitColor = Color.FromArgb(0x50, 0x50, 0x50);
|
|
Color currentColor = Color.FromArgb(0, 0, 0);
|
|
|
|
Size newWindowSize = new Size(bmp.Height - Convert.ToInt32((float)bmp.Height / 100f * 25f), bmp.Height - Convert.ToInt32((float)bmp.Height / 100f * 35f));
|
|
|
|
while (currentColor.R <= limitColor.R && currentColor.G <= limitColor.G && currentColor.B <= limitColor.B && currentPosition > 0)
|
|
{
|
|
currentPosition--;
|
|
currentColor = bmp.GetPixel(currentPosition, height);
|
|
}
|
|
|
|
//Its here to let the new window include a little bit of the right
|
|
int CorrectedX = currentPosition - (newWindowSize.Width) + Convert.ToInt32((float)newWindowSize.Width / 100f * 10f);
|
|
int CorrectedY = Convert.ToInt32((float)newWindowSize.Height / 100f * 35f);
|
|
if (CorrectedX <= 0)
|
|
return new Rectangle(0, 0, newWindowSize.Width, newWindowSize.Height);
|
|
|
|
return new Rectangle(CorrectedX, CorrectedY, newWindowSize.Width, newWindowSize.Height);
|
|
}
|
|
//This method has been created with the help of chatGPT
|
|
/// <summary>
|
|
/// Methods that compares a list of colors to see wich is the closest from the input color and decide wich tyre type it is
|
|
/// </summary>
|
|
/// <param name="inputColor">The color that you found</param>
|
|
/// <returns>The tyre type</returns>
|
|
public Tyre.Type GetTyreTypeFromColor(Color inputColor)
|
|
{
|
|
Tyre.Type type = Tyre.Type.Undefined;
|
|
List<Color> colors = new List<Color>();
|
|
//dont forget that if for some reason someday F1 adds a new Tyre type you will need to add it in the constants but also here in the list
|
|
//You will also need to add it below in the Tyre object's enum and add an if in the end of this method
|
|
colors.Add(SOFT_TYRE_COLOR);
|
|
colors.Add(MEDIUM_TYRE_COLOR);
|
|
colors.Add(HARD_TYRE_COLOR);
|
|
colors.Add(INTER_TYRE_COLOR);
|
|
colors.Add(WET_TYRE_COLOR);
|
|
colors.Add(EMPTY_COLOR);
|
|
|
|
Color closestColor = colors[0];
|
|
int closestDistance = int.MaxValue;
|
|
foreach (Color color in colors)
|
|
{
|
|
int distance = Math.Abs(color.R - inputColor.R) + Math.Abs(color.G - inputColor.G) + Math.Abs(color.B - inputColor.B);
|
|
if (distance < closestDistance)
|
|
{
|
|
closestColor = color;
|
|
closestDistance = distance;
|
|
}
|
|
}
|
|
|
|
//We cant use a switch as the colors cant be constants ...
|
|
if (closestColor == SOFT_TYRE_COLOR)
|
|
type = Tyre.Type.Soft;
|
|
if (closestColor == MEDIUM_TYRE_COLOR)
|
|
type = Tyre.Type.Medium;
|
|
if (closestColor == HARD_TYRE_COLOR)
|
|
type = Tyre.Type.Hard;
|
|
if (closestColor == INTER_TYRE_COLOR)
|
|
type = Tyre.Type.Inter;
|
|
if (closestColor == WET_TYRE_COLOR)
|
|
type = Tyre.Type.Wet;
|
|
if (closestColor == EMPTY_COLOR)
|
|
return Tyre.Type.Undefined;
|
|
|
|
return type;
|
|
}
|
|
}
|
|
}
|