rj-action-library/Runtime/Godot/Extensions/ImageExtensions.cs

62 lines
1.7 KiB
C#

using Godot;
namespace Rokojori
{
public static class ImageExtensions
{
public enum EdgeMode
{
Clamp,
Repeat,
TransparentBlack,
}
public static Color GetPixel( this Image image, int x, int y, EdgeMode mode )
{
if ( x < 0 || y < 0 || x >= image.GetSize().X || y >= image.GetSize().Y )
{
if ( mode == EdgeMode.TransparentBlack )
{
return new Color( 0, 0, 0, 0 );
}
if ( mode == EdgeMode.Repeat )
{
x = MathX.Repeat( x, image.GetSize().X );
y = MathX.Repeat( y, image.GetSize().Y );
}
if ( mode == EdgeMode.Clamp )
{
x = Mathf.Clamp( x, 0, image.GetSize().X );
y = Mathf.Clamp( y, 0, image.GetSize().Y );
}
}
return image.GetPixel( x, y );
}
public static Color SampleNearest( this Image image, Vector2 uv, EdgeMode mode = EdgeMode.Clamp )
{
var pixelUV = uv * image.GetSize();
var roundedPixelUV = pixelUV.RoundToInt();
return image.GetPixel( roundedPixelUV.X, roundedPixelUV.Y, mode );
}
public static Color SampleLinear( this Image image, Vector2 uv, EdgeMode mode = EdgeMode.Clamp )
{
var pixelUV = uv * image.GetSize();
var lowUV = pixelUV.FloorToInt().Max( 0 );
var highUV = ( lowUV + Vector2I.One ).Min( image.GetSize() - Vector2I.One );
var mix = pixelUV - lowUV;
var xTop = ColorX.Lerp( image.GetPixel( lowUV.X, lowUV.Y, mode ), image.GetPixel( highUV.X, lowUV.Y, mode ), mix.X );
var xLow = ColorX.Lerp( image.GetPixel( highUV.X, lowUV.Y, mode ), image.GetPixel( highUV.X, highUV.Y, mode ), mix.X );
return ColorX.Lerp( xTop, xLow, mix.Y );
}
}
}