Expanded LoadImage to cover all channel counts

This commit is contained in:
Samuele Lorefice
2025-03-28 22:10:10 +01:00
parent ccaae9befd
commit e158cfc95b

View File

@@ -59,6 +59,8 @@ public static class ImageUtil {
public static T[,] LoadImage<T>(string path) where T : struct, IEquatable<T> { public static T[,] LoadImage<T>(string path) where T : struct, IEquatable<T> {
var image = new MagickImage(path); var image = new MagickImage(path);
var pixels = image.GetPixels().ToArray(); var pixels = image.GetPixels().ToArray();
uint width = image.Width;
uint height = image.Height;
if (pixels == null) throw new ("Failed to read image."); if (pixels == null) throw new ("Failed to read image.");
T[,] result = new T[image.Width, image.Height]; T[,] result = new T[image.Width, image.Height];
@@ -70,34 +72,67 @@ public static class ImageUtil {
case float[,] f: case float[,] f:
//remainder of index / channels must be 0 //remainder of index / channels must be 0
var data = pixels.Where((_, i) => i % channels != 0).ToArray(); var data = pixels.Where((_, i) => i % channels != 0).ToArray();
for (int i = 0; i < image.Width * image.Height; i++) { return LoadFloat(data, width, height) as T[,] ?? throw new InvalidOperationException();
int x = (int)(i % image.Width); case Vector2[,]:
int y = (int)(i / image.Width);
result[x, y] = (T)(object)data[i];
}
break;
case Vector2[,]v2:
//can't read 1 channel images //can't read 1 channel images
if (channels < 2) throw new NotSupportedException($"Image has {channels} channels, only 2+ channels are supported."); if (channels < 2) throw new NotSupportedException($"Image has {channels} channels, only 2+ channels are supported.");
//remainder of index / channels must be 0 or 1 (2 values) //remainder of index / channels must be 0 or 1 (2 values)
var data2 = pixels.Where((_, i) => i % channels >= 1).ToArray(); var data2 = pixels.Where((_, i) => i % channels >= 1).ToArray();
break; return LoadVec2(data2, width, height) as T[,] ?? throw new InvalidOperationException();
case Vector3[,]v3: case Vector3[,]:
//can't read <2 channel images //can't read <2 channel images
if(channels<3) throw new NotSupportedException($"Image has {channels} channels, only 3+ channels are supported."); if(channels<3) throw new NotSupportedException($"Image has {channels} channels, only 3+ channels are supported.");
//remainder of index / channels must be 0, 1 or 2 (3 values) //remainder of index / channels must be 0, 1 or 2 (3 values)
var data3 = pixels.Where((_, i) => i % channels >= 2).ToArray(); var data3 = pixels.Where((_, i) => i % channels >= 2).ToArray();
break; return LoadVec3(data3, width, height) as T[,] ?? throw new InvalidOperationException();
case Vector4[,]v4: case Vector4[,]v4:
//can't read <3 channel images //can't read <3 channel images
if(channels<4) throw new NotSupportedException($"Image has {channels} channels, only 4+ channels are supported."); if(channels<4) throw new NotSupportedException($"Image has {channels} channels, only 4+ channels are supported.");
//remainder of index / channels must be between 0 or 3 (4 values) //remainder of index / channels must be between 0 or 3 (4 values)
var data4 = pixels.Where((_, i) => i % channels >= 3).ToArray(); var data4 = pixels.Where((_, i) => i % channels >= 3).ToArray();
break; return LoadVec4(data4, width, height) as T[,] ?? throw new InvalidOperationException();
default: default:
throw new NotSupportedException($"Type {typeof(T)} is not supported."); throw new NotSupportedException($"Type {typeof(T)} is not supported.");
} }
}
private static float[,] LoadFloat(float[] array, uint width, uint height) {
float[,] result = new float[width, height];
for (int i = 0; i < width * height; i++) {
uint x = (uint)(i % width);
uint y = (uint)(i / width);
result[x, y] = array[i];
}
return result;
}
private static Vector2[,] LoadVec2(float[] array, uint width, uint height) {
Vector2[,] result = new Vector2[width, height];
for (int i = 0; i < width * height; i++) {
uint x = (uint)(i % width);
uint y = (uint)(i / width);
result[x, y] = new(array[i * 2], array[i * 2 + 1]);
}
return result;
}
private static Vector3[,] LoadVec3(float[] array, uint width, uint height) {
Vector3[,] result = new Vector3[width, height];
for (int i = 0; i < width * height; i++) {
uint x = (uint)(i % width);
uint y = (uint)(i / width);
result[x, y] = new(array[i * 3], array[i * 3 + 1], array[i * 3 + 2]);
}
return result;
}
private static Vector4[,] LoadVec4(float[] array, uint width, uint height) {
Vector4[,] result = new Vector4[width, height];
for (int i = 0; i < width * height; i++) {
uint x = (uint)(i % width);
uint y = (uint)(i / width);
result[x, y] = new(array[i * 4], array[i * 4 + 1], array[i * 4 + 2], array[i * 4 + 3]);
}
return result; return result;
} }
} }