/// <summary> /// Saves this <see cref="FramebufferObject"/>'s image to a stream. You can't save multisampled framebuffers. /// </summary> /// <param name="framebuffer">The <see cref="FramebufferObject"/> whose image to save.</param> /// <param name="stream">The stream to save the framebuffer image to.</param> /// <param name="imageFormat">The format the image will be saved as.</param> /// <param name="flip">Whether to flip the image after the pixels are read.</param> public static void SaveAsImage(this FramebufferObject framebuffer, Stream stream, SaveImageFormat imageFormat, bool flip = false) { if (framebuffer == null) { throw new ArgumentNullException(nameof(framebuffer)); } if (stream == null) { throw new ArgumentNullException(nameof(stream)); } IImageFormat format = ImageUtils.GetFormatFor(imageFormat); using Image <Rgba32> image = new Image <Rgba32>((int)framebuffer.Width, (int)framebuffer.Height); framebuffer.ReadPixels(image, flip); image.Save(stream, format); }
/// <summary> /// Reads pixels from this <see cref="FramebufferObject"/>. /// </summary> /// <param name="framebuffer">The <see cref="FramebufferObject"/> to read pixels from.</param> /// <param name="x">The x position of the first pixel to read.</param> /// <param name="y">The y position of the first pixel to read.</param> /// <param name="image">The image in which to write the pixel data.</param> /// <param name="flip">Whether to flip the image after the pixels are read.</param> public static void ReadPixels(this FramebufferObject framebuffer, int x, int y, Image <Rgba32> image, bool flip = false) { if (framebuffer == null) { throw new ArgumentNullException(nameof(framebuffer)); } if (image == null) { throw new ArgumentNullException(nameof(image)); } if (!image.TryGetSinglePixelSpan(out Span <Rgba32> pixels)) { throw new InvalidDataException(ImageUtils.ImageNotContiguousError); } framebuffer.ReadPixels(pixels, x, y, (uint)image.Width, (uint)image.Height); if (flip) { image.Mutate(x => x.Flip(FlipMode.Vertical)); } }