/
EugenyCh7
/
Puppet2D.Net
Обзор
Документация
Войти
/
EugenyCh7
/
Puppet2D.Net
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Puppet2D.Graphics/Image.cs
387 строк
15 KB
EugenyCh7
comments fix
24 июл 2025, 22:54
24 июл 2025, 22:54
421ed1f
Код
Авторство
О чём код?
using System; using System.IO; using System.Runtime.InteropServices; using System.Security; using Puppet2D.System; namespace Puppet2D.Graphics { /// <summary> /// Image is the low-level class for loading and /// manipulating images /// </summary> public class Image : ObjectBase { /// <summary> /// Construct the image with black color /// </summary> /// <param name="width">Image width</param> /// <param name="height">Image height</param> /// <exception cref="LoadingFailedException" /> public Image(uint width, uint height) : this(width, height, Color.Black) { } /// <summary> /// Construct the image from a single color /// </summary> /// <param name="width">Image width</param> /// <param name="height">Image height</param> /// <param name="color">Color to fill the image with</param> /// <exception cref="LoadingFailedException" /> public Image(uint width, uint height, Color color) : base(sfImage_createFromColor(width, height, color)) { if (IsInvalid) { throw new LoadingFailedException("image"); } } /// <summary> /// Construct the image from a file /// </summary> /// <param name="filename">Path of the image file to load</param> /// <exception cref="LoadingFailedException" /> public Image(string filename) : base(sfImage_createFromFile(filename)) { if (IsInvalid) { throw new LoadingFailedException("image", filename); } } /// <summary> /// Construct the image from a file in a stream /// </summary> /// <param name="stream">Stream containing the file contents</param> /// <exception cref="LoadingFailedException" /> public Image(Stream stream) : base(IntPtr.Zero) { using (var adaptor = new Puppet2D.System.StreamAdaptor(stream)) { CPointer = sfImage_createFromStream(adaptor.InputStreamPtr); } if (IsInvalid) { throw new LoadingFailedException("image"); } } /// <summary> /// Construct the image from a file in memory /// </summary> /// <param name="bytes">Byte array containing the file contents</param> /// <exception cref="LoadingFailedException" /> public Image(byte[] bytes) : base(IntPtr.Zero) { GCHandle pin = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { CPointer = sfImage_createFromMemory(pin.AddrOfPinnedObject(), (UIntPtr)bytes.Length); } finally { pin.Free(); } if (IsInvalid) { throw new LoadingFailedException("image"); } } /// <summary> /// Construct the image directly from an array of pixels /// </summary> /// <param name="pixels">2 dimensions array containing the pixels</param> /// <exception cref="LoadingFailedException" /> public Image(Color[,] pixels) : base(IntPtr.Zero) { uint Width = (uint)pixels.GetLength(0); uint Height = (uint)pixels.GetLength(1); // Transpose the array (.Net gives dimensions in reverse order of what Puppet2D expects) Color[,] transposed = new Color[Height, Width]; for (int x = 0; x < Width; ++x) { for (int y = 0; y < Height; ++y) { transposed[y, x] = pixels[x, y]; } } unsafe { fixed (Color* PixelsPtr = transposed) { CPointer = sfImage_createFromPixels(Width, Height, (byte*)PixelsPtr); } } if (IsInvalid) { throw new LoadingFailedException("image"); } } /// <summary> /// Construct the image directly from an array of pixels /// </summary> /// <param name="width">Image width</param> /// <param name="height">Image height</param> /// <param name="pixels">array containing the pixels</param> /// <exception cref="LoadingFailedException" /> public Image(uint width, uint height, byte[] pixels) : base(IntPtr.Zero) { unsafe { fixed (byte* PixelsPtr = pixels) { CPointer = sfImage_createFromPixels(width, height, PixelsPtr); } } if (IsInvalid) { throw new LoadingFailedException("image"); } } /// <summary> /// Construct the image from another image /// </summary> /// <param name="copy">Image to copy</param> public Image(Image copy) : base(sfImage_copy(copy.CPointer)) { } /// <summary> /// Save the contents of the image to a file /// </summary> /// <param name="filename">Path of the file to save (overwritten if already exist)</param> /// <returns>True if saving was successful</returns> public bool SaveToFile(string filename) => sfImage_saveToFile(CPointer, filename); /// <summary> /// Save the image to a buffer in memory /// /// The format of the image must be specified. /// The supported image formats are bmp, png, tga and jpg. /// This function fails if the image is empty, or if /// the format was invalid. /// </summary> /// <param name="output">Byte array filled with encoded data</param> /// <param name="format">Encoding format to use</param> /// <returns>True if saving was successful</returns> public bool SaveToMemory(out byte[] output, string format) { using (Puppet2D.System.Buffer buffer = new Puppet2D.System.Buffer()) { var success = sfImage_saveToMemory(CPointer, buffer.CPointer, format); output = success ? buffer.GetData() : Array.Empty<byte>(); return success; } } /// <summary> /// Create a transparency mask from a specified colorkey /// </summary> /// <param name="color">Color to become transparent</param> public void CreateMaskFromColor(Color color) { CreateMaskFromColor(color, 0); } /// <summary> /// Create a transparency mask from a specified colorkey /// </summary> /// <param name="color">Color to become transparent</param> /// <param name="alpha">Alpha value to use for transparent pixels</param> public void CreateMaskFromColor(Color color, byte alpha) { sfImage_createMaskFromColor(CPointer, color, alpha); } /// <summary> /// Copy pixels from another image onto this one. /// This function does a slow pixel copy and should only /// be used at initialization time /// </summary> /// <param name="source">Source image to copy</param> /// <param name="destX">X coordinate of the destination position</param> /// <param name="destY">Y coordinate of the destination position</param> public void Copy(Image source, uint destX, uint destY) { Copy(source, destX, destY, new IntRect(0, 0, 0, 0)); } /// <summary> /// Copy pixels from another image onto this one. /// This function does a slow pixel copy and should only /// be used at initialization time /// </summary> /// <param name="source">Source image to copy</param> /// <param name="destX">X coordinate of the destination position</param> /// <param name="destY">Y coordinate of the destination position</param> /// <param name="sourceRect">Sub-rectangle of the source image to copy</param> public void Copy(Image source, uint destX, uint destY, IntRect sourceRect) { Copy(source, destX, destY, sourceRect, false); } /// <summary> /// Copy pixels from another image onto this one. /// This function does a slow pixel copy and should only /// be used at initialization time /// </summary> /// <param name="source">Source image to copy</param> /// <param name="destX">X coordinate of the destination position</param> /// <param name="destY">Y coordinate of the destination position</param> /// <param name="sourceRect">Sub-rectangle of the source image to copy</param> /// <param name="applyAlpha">Should the copy take in account the source transparency?</param> public void Copy(Image source, uint destX, uint destY, IntRect sourceRect, bool applyAlpha) { sfImage_copyImage(CPointer, source.CPointer, destX, destY, sourceRect, applyAlpha); } /// <summary> /// Get a pixel from the image /// </summary> /// <param name="x">X coordinate of pixel in the image</param> /// <param name="y">Y coordinate of pixel in the image</param> /// <returns>Color of pixel (x, y)</returns> public Color GetPixel(uint x, uint y) => sfImage_getPixel(CPointer, x, y); /// <summary> /// Change the color of a pixel /// </summary> /// <param name="x">X coordinate of pixel in the image</param> /// <param name="y">Y coordinate of pixel in the image</param> /// <param name="color">New color for pixel (x, y)</param> public void SetPixel(uint x, uint y, Color color) { sfImage_setPixel(CPointer, x, y, color); } /// <summary> /// Get a copy of the array of pixels (RGBA 8 bits integers components) /// Array size is Width x Height x 4 /// </summary> /// <returns>Array of pixels</returns> public byte[] Pixels { get { Vector2u size = Size; byte[] PixelsPtr = new byte[size.X * size.Y * 4]; Marshal.Copy(sfImage_getPixelsPtr(CPointer), PixelsPtr, 0, PixelsPtr.Length); return PixelsPtr; } } /// <summary> /// Size of the image, in pixels /// </summary> public Vector2u Size => sfImage_getSize(CPointer); /// <summary> /// Flip the image horizontally /// </summary> public void FlipHorizontally() { sfImage_flipHorizontally(CPointer); } /// <summary> /// Flip the image vertically /// </summary> public void FlipVertically() { sfImage_flipVertically(CPointer); } /// <summary> /// Provide a string describing the object /// </summary> /// <returns>String description of the object</returns> public override string ToString() { if (IsInvalid) return MakeDisposedObjectString(); return $"[Image] Size({Size})"; } /// <summary> /// Internal constructor /// </summary> /// <param name="cPointer">Pointer to the object in C library</param> internal Image(IntPtr cPointer) : base(cPointer) { } /// <summary> /// Handle the destruction of the object /// </summary> /// <param name="disposing">Is the GC disposing the object, or is it an explicit call ?</param> protected override void Destroy(bool disposing) { sfImage_destroy(CPointer); } #region Imports [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern IntPtr sfImage_createFromColor(uint Width, uint Height, Color Col); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private unsafe static extern IntPtr sfImage_createFromPixels(uint Width, uint Height, byte* Pixels); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern IntPtr sfImage_createFromFile(string Filename); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private unsafe static extern IntPtr sfImage_createFromStream(IntPtr stream); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private unsafe static extern IntPtr sfImage_createFromMemory(IntPtr data, UIntPtr size); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern IntPtr sfImage_copy(IntPtr Image); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern void sfImage_destroy(IntPtr CPointer); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern bool sfImage_saveToFile(IntPtr CPointer, string Filename); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern bool sfImage_saveToMemory(IntPtr CPointer, IntPtr bufferOutput, string format); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern void sfImage_createMaskFromColor(IntPtr CPointer, Color Col, byte Alpha); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern void sfImage_copyImage(IntPtr CPointer, IntPtr Source, uint DestX, uint DestY, IntRect SourceRect, bool applyAlpha); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern void sfImage_setPixel(IntPtr CPointer, uint X, uint Y, Color Col); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern Color sfImage_getPixel(IntPtr CPointer, uint X, uint Y); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern IntPtr sfImage_getPixelsPtr(IntPtr CPointer); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern Vector2u sfImage_getSize(IntPtr CPointer); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern void sfImage_flipHorizontally(IntPtr CPointer); [DllImport(CSFML.graphics, CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] private static extern void sfImage_flipVertically(IntPtr CPointer); #endregion } }