Agrarsense
ColorUtilities.cpp
Go to the documentation of this file.
1// Copyright (c) 2023 FrostBit Software Lab at the Lapland University of Applied Sciences
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
6#include "ColorUtilities.h"
7#include "Misc/DefaultValueHelper.h"
8
9FLinearColor UColorUtilities::HexToLinearColor(const FString& HexString, bool& bSuccess)
10{
11
12 if (IsValidHexString(HexString))
13 {
14 bSuccess = true;
15 /*
16 Creates a color value from the given hexadecimal string.
17 Supported formats are: RGB, RRGGBB, RRGGBBAA, RGB, #RRGGBB, #RRGGBBAA The corresponding color value.
18 */
19 FColor Color = FColor::FromHex(HexString);
20 return Color.ReinterpretAsLinear();
21 }
22 else
23 {
24 //UE_LOG(LogTemp, Warning, TEXT("Invalid Hex String Format: %s"), *HexString);
25 bSuccess = false;
26 return FLinearColor::White;
27 }
28
29 // FString CleanHex = HexString.Replace(TEXT("#"), TEXT("")); // Remove #
30
31 // if (CleanHex.Len() != 6 && CleanHex.Len() != 8)
32 //{
33 // UE_LOG(LogTemp, Warning, TEXT("Invalid Hex Color Length: %s"), *HexString);
34 // return FLinearColor::White;
35 // }
36
37 // int32 R, G, B, A = 255; // Default alpha to 255
38
40 // FDefaultValueHelper::ParseInt(CleanHex.Mid(0, 2), R, 16);
41 // FDefaultValueHelper::ParseInt(CleanHex.Mid(2, 2), G, 16);
42 // FDefaultValueHelper::ParseInt(CleanHex.Mid(4, 2), B, 16);
43
44 // if (CleanHex.Len() == 8)
45 //{
46 // FDefaultValueHelper::ParseInt(CleanHex.Mid(6, 2), A, 16);
47 // }
48
49 // return FLinearColor(R / 255.0f, G / 255.0f, B / 255.0f, A / 255.0f);
50}
51
52FLinearColor UColorUtilities::RGBStringToLinearColor(const FString& ColorString, bool& bSuccess)
53{
54 if (IsValidRGBString(ColorString))
55 {
56 bSuccess = true;
57 TArray<FString> Components;
58 ColorString.ParseIntoArray(Components, TEXT(","), true);
59
60 int32 R = 0, G = 0, B = 0, A = 255; // Default alpha to 255 (fully opaque)
61
62 // Parse integer values from the string components
63 FDefaultValueHelper::ParseInt(Components[0], R);
64 FDefaultValueHelper::ParseInt(Components[1], G);
65 FDefaultValueHelper::ParseInt(Components[2], B);
66
67 if (Components.Num() == 4) // If alpha is provided
68 {
69 FDefaultValueHelper::ParseInt(Components[3], A);
70 }
71
72 // Convert to linear color
73 return FLinearColor(R / 255.0f, G / 255.0f, B / 255.0f, A / 255.0f);
74 }
75
76 // Invalid string format
77 bSuccess = false;
78
79 //UE_LOG(LogTemp, Warning, TEXT("Invalid Color String Format: %s"), *ColorString);
80
81 return FLinearColor::White;
82}
83
84FString UColorUtilities::LinearColorToHex(const FLinearColor& Color, bool bIncludeAlpha, bool bAddPrefix)
85{
86 FColor ConvertedColor = Color.QuantizeRound(); // Converts FLinearColor to FColor
87 FString HexString = ConvertedColor.ToHex(); // Returns RRGGBBAA format
88
89 if (!bIncludeAlpha)
90 {
91 HexString = HexString.Left(6); // Trim the last two characters (AA)
92 }
93
94 if (bAddPrefix)
95 {
96 HexString = FString("#") + HexString;
97 }
98
99 return HexString;
100
101 // int32 R = FMath::RoundToInt(Color.R * 255);
102 // int32 G = FMath::RoundToInt(Color.G * 255);
103 // int32 B = FMath::RoundToInt(Color.B * 255);
104 // int32 A = FMath::RoundToInt(Color.A * 255);
105
106 // FString HexString = FString::Printf(TEXT("#%02X%02X%02X"), R, G, B);
107
108 // if (bIncludeAlpha)
109 //{
110 // HexString += FString::Printf(TEXT("%02X"), A);
111 // }
112
113 // return HexString;
114}
115
116FString UColorUtilities::LinearColorToRGBString(const FLinearColor& Color, bool bIncludeAlpha)
117{
118 int32 R = FMath::RoundToInt(Color.R * 255);
119 int32 G = FMath::RoundToInt(Color.G * 255);
120 int32 B = FMath::RoundToInt(Color.B * 255);
121 int32 A = FMath::RoundToInt(Color.A * 255);
122
123 if (bIncludeAlpha)
124 {
125 return FString::Printf(TEXT("%d,%d,%d,%d"), R, G, B, A);
126 }
127 else
128 {
129 return FString::Printf(TEXT("%d,%d,%d"), R, G, B);
130 }
131}
132
133bool UColorUtilities::IsValidRGBString(const FString& ColorString)
134{
135 FString TrimmedString = ColorString.TrimStartAndEnd(); // Remove whitespace
136 TArray<FString> Components;
137 TrimmedString.ParseIntoArray(Components, TEXT(","), true);
138
139 // RGB(A) must have 3 or 4 integer values
140 if (Components.Num() < 3 || Components.Num() > 4)
141 {
142 return false;
143 }
144
145 for (const FString& Component : Components)
146 {
147 int32 Value;
148 if (!FDefaultValueHelper::ParseInt(Component, Value) || Value < 0 || Value > 255)
149 {
150 return false; // Must be an integer between 0-255
151 }
152 }
153
154 return true; // Valid RGB or RGBA format
155}
156
157bool UColorUtilities::IsValidHexString(const FString& ColorString)
158{
159 FString TrimmedString = ColorString.TrimStartAndEnd().Replace(TEXT("#"), TEXT("")); // Remove '#' if present
160
161 // Must be exactly 6 (RRGGBB) or 8 (RRGGBBAA) characters long, shorthand (RGB) not supported
162 if (TrimmedString.Len() != 6 && TrimmedString.Len() != 8)
163 {
164 return false;
165 }
166
167 // Ensure all characters are valid hex digits (0-9, A-F, a-f)
168 for (TCHAR Char : TrimmedString)
169 {
170 if (!FChar::IsHexDigit(Char))
171 {
172 return false;
173 }
174 }
175
176 return true; // Valid hex format
177}
178
179FLinearColor UColorUtilities::AutoDetectColorStringToLinearColor(const FString& ColorString, bool& bSuccess)
180{
181 FString TrimmedString = ColorString.TrimStartAndEnd(); // Remove leading/trailing spaces
182 FLinearColor ConvertedColor;
183
184 // First try to convert string to linear color assuming it's rgb
185 ConvertedColor = RGBStringToLinearColor(TrimmedString, bSuccess);
186
187 // If that fails, assume it's hex
188 if (!bSuccess)
189 {
190 ConvertedColor = HexToLinearColor(TrimmedString, bSuccess);
191 }
192
193 // return converted color (and bSuccess). ConvertedColor set to FLinearColor::White if conversion failed in previous steps
194 return ConvertedColor;
195}
static bool IsValidRGBString(const FString &ColorString)
static FLinearColor HexToLinearColor(const FString &HexString, bool &bSuccess)
Converts a hex color code (e.g. "#FF00FF" or "#FF00FFAA" or "FF00FF" or "FF00FFAA) to an FLinearColor...
static FString LinearColorToHex(const FLinearColor &Color, bool bIncludeAlpha, bool bAddPrefix)
static FLinearColor RGBStringToLinearColor(const FString &ColorString, bool &bSuccess)
Converts a comma-separated color string ("r,g,b" or "r,g,b,a") to an FLinearColor.
static FLinearColor AutoDetectColorStringToLinearColor(const FString &ColorString, bool &bSuccess)
Tries to auto detect format for color string, and convert it to linear color accordingly.
static bool IsValidHexString(const FString &ColorString)
static FString LinearColorToRGBString(const FLinearColor &Color, bool bIncludeAlpha)