/// <summary> /// Creates a mouse cursor from the specified pixels. /// </summary> /// <param name="pixels">Pixels to use as the cursor image.</param> /// <param name="origin">A point in the pixels that is used as the cursor position.</param> /// <param name="sourceRectangle">Optional part of the image to use as the cursor.</param> public static MouseCursor FromPixels( IReadOnlyPixelRows pixels, Point origin, Rectangle?sourceRectangle = null) { if (pixels == null) { throw new ArgumentNullException(nameof(pixels)); } Rectangle rect = sourceRectangle ?? pixels.GetBounds(); if (!pixels.GetBounds().Contains(rect)) { throw new ArgumentOutOfRangeException( nameof(sourceRectangle), "The source rectangle is outside the pixel buffer."); } IReadOnlyPixelMemory <Color>?pixelBuffer = null; try { if (rect.Position == Point.Zero && pixels is IReadOnlyPixelMemory <Color> rgbaMemory && rgbaMemory.IsPaddedPixelContiguous()) { pixelBuffer = rgbaMemory; } else { pixelBuffer = Image.LoadPixels <Color>(pixels.ProjectRows(x => x.Crop(rect))); } return(PlatformFromPixels(pixelBuffer, rect.Width, rect.Height, origin)); } finally { pixelBuffer?.Dispose(); } }
public static void LoadPixels <TPixelFrom, TPixelTo>( IReadOnlyPixelRows pixels, IPixelBuffer <TPixelTo> destination, Rectangle?sourceRectangle = null) where TPixelFrom : unmanaged, IPixel where TPixelTo : unmanaged, IPixel <TPixelTo> { if (pixels == null) { throw new ArgumentNullException(nameof(pixels)); } if (destination == null) { throw new ArgumentNullException(nameof(destination)); } var rect = sourceRectangle ?? pixels.GetBounds(); ImagingArgumentGuard.AssertNonEmptyRectangle(rect, nameof(sourceRectangle)); Span <byte> rowByteBuffer = stackalloc byte[4096]; var rowBuffer = MemoryMarshal.Cast <byte, TPixelFrom>(rowByteBuffer); for (int y = 0; y < rect.Height; y++) { var dstRow = destination.GetPixelRowSpan(y); int offsetX = 0; do { int left = rect.Width - offsetX; int count = Math.Min(rowBuffer.Length, left); var slice = rowBuffer.Slice(0, count); pixels.GetPixelByteRow(rect.X + offsetX, rect.Y + y, MemoryMarshal.AsBytes(slice)); ConvertPixels(slice, dstRow); dstRow = dstRow[count..];