using System; using Robust.Shared.Maths; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using Color = Robust.Shared.Maths.Color; namespace Robust.Client.Utility { public static class ImageSharpExt { public static Color ConvertImgSharp(this Rgba32 color) { return new Color(color.R, color.G, color.B, color.A); } public static Rgba32 ConvertImgSharp(this Color color) { return new Rgba32(color.R, color.G, color.B, color.A); } /// /// Blit an image into another, with the specified offset. /// /// The image to copy data from. /// The sub section of that will be copied. /// /// The offset into that data will be copied into. /// /// The image to copy to. /// The type of pixel stored in the images. public static void Blit(this Image source, UIBox2i sourceRect, Image destination, Vector2i destinationOffset) where T : unmanaged, IPixel { // TODO: Bounds checks. Blit(source.GetPixelSpan(), source.Width, sourceRect, destination, destinationOffset); } public static void Blit(this ReadOnlySpan source, int sourceWidth, UIBox2i sourceRect, Image destination, Vector2i destinationOffset) where T : unmanaged, IPixel { var dstSpan = destination.GetPixelSpan(); var dstWidth = destination.Width; var (ox, oy) = destinationOffset; for (var y = 0; y < sourceRect.Height; y++) { var sourceRowOffset = sourceWidth * (y + sourceRect.Top) + sourceRect.Left; var destRowOffset = dstWidth * (y + oy) + ox; for (var x = 0; x < sourceRect.Width; x++) { var pixel = source[x + sourceRowOffset]; dstSpan[x + destRowOffset] = pixel; } } } /// /// Gets a to the backing data if the backing group consists of a single contiguous memory buffer. /// /// The referencing the memory area. /// Thrown if the image is not a single contiguous buffer. public static Span GetPixelSpan(this Image image) where T : unmanaged, IPixel { if (!image.TryGetSinglePixelSpan(out var span)) { throw new ArgumentException("Image is not backed by a single buffer, cannot fetch span."); } return span; } } }