using SkiaSharp; using System; namespace Ryujinx.Graphics.Gpu.Overlay { /// /// Image overlay element /// public class ImageElement : OverlayElement { private SKBitmap? _bitmap; private byte[]? _imageData; private string? _imagePath; public SKFilterQuality FilterQuality { get; set; } = SKFilterQuality.Medium; public bool MaintainAspectRatio { get; set; } = true; public ImageElement() { } public ImageElement(float x, float y, float width, float height, byte[] imageData) { X = x; Y = y; Width = width; Height = height; SetImageData(imageData); } public ImageElement(float x, float y, float width, float height, string imagePath) { X = x; Y = y; Width = width; Height = height; SetImagePath(imagePath); } /// /// Set image from byte array /// public void SetImageData(byte[] imageData) { _imageData = imageData; _imagePath = null; LoadBitmap(); } /// /// Set image from file path /// public void SetImagePath(string imagePath) { _imagePath = imagePath; _imageData = null; LoadBitmap(); } /// /// Set image from existing SKBitmap /// public void SetBitmap(SKBitmap bitmap) { _bitmap?.Dispose(); _bitmap = bitmap; _imageData = null; _imagePath = null; } private void LoadBitmap() { try { _bitmap?.Dispose(); _bitmap = null; if (_imageData != null) { _bitmap = SKBitmap.Decode(_imageData); } else if (!string.IsNullOrEmpty(_imagePath)) { _bitmap = SKBitmap.Decode(_imagePath); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"Failed to load image: {ex.Message}"); _bitmap = null; } } public override void Render(SKCanvas canvas, float globalOpacity = 1.0f) { if (!IsVisible || _bitmap == null || Width <= 0 || Height <= 0) return; float effectiveOpacity = Opacity * globalOpacity; using var paint = new SKPaint { FilterQuality = FilterQuality, Color = SKColors.White.WithAlpha((byte)(255 * effectiveOpacity)) }; var sourceRect = new SKRect(0, 0, _bitmap.Width, _bitmap.Height); var destRect = new SKRect(X, Y, X + Width, Y + Height); if (MaintainAspectRatio) { // Calculate aspect ratio preserving destination rectangle float sourceAspect = (float)_bitmap.Width / _bitmap.Height; float destAspect = Width / Height; if (sourceAspect > destAspect) { // Source is wider, fit to width float newHeight = Width / sourceAspect; float yOffset = (Height - newHeight) / 2; destRect = new SKRect(X, Y + yOffset, X + Width, Y + yOffset + newHeight); } else { // Source is taller, fit to height float newWidth = Height * sourceAspect; float xOffset = (Width - newWidth) / 2; destRect = new SKRect(X + xOffset, Y, X + xOffset + newWidth, Y + Height); } } canvas.DrawBitmap(_bitmap, sourceRect, destRect, paint); } protected override void Dispose(bool disposing) { if (disposing) { _bitmap?.Dispose(); _bitmap = null; } base.Dispose(disposing); } } }