using System;
using System.Runtime.InteropServices;
using System.Security;
using System.IO;
using System.Runtime.ConstrainedExecution;
namespace SFML
{
namespace Graphics
{
////////////////////////////////////////////////////////////
///
/// Image is the low-level class for loading and
/// manipulating images
///
////////////////////////////////////////////////////////////
public class Image : ObjectBase
{
////////////////////////////////////////////////////////////
///
/// Default constructor (invalid image)
///
///
////////////////////////////////////////////////////////////
public Image() :
base(sfImage_Create())
{
if (This == IntPtr.Zero)
throw new LoadingFailedException("image");
}
////////////////////////////////////////////////////////////
///
/// Construct the image with black color
///
/// Image width
/// Image height
///
////////////////////////////////////////////////////////////
public Image(uint width, uint height) :
this(width, height, Color.Black)
{
}
////////////////////////////////////////////////////////////
///
/// Construct the image from a single color
///
/// Image width
/// Image height
/// Color to fill the image with
///
////////////////////////////////////////////////////////////
public Image(uint width, uint height, Color color) :
base(sfImage_CreateFromColor(width, height, color))
{
if (This == IntPtr.Zero)
throw new LoadingFailedException("image");
}
////////////////////////////////////////////////////////////
///
/// Construct the image from a file
///
/// Path of the image file to load
///
////////////////////////////////////////////////////////////
public Image(string filename) :
base(sfImage_CreateFromFile(filename))
{
if (This == IntPtr.Zero)
throw new LoadingFailedException("image", filename);
}
////////////////////////////////////////////////////////////
///
/// Construct the image from a file in a stream
///
/// Stream containing the file contents
///
////////////////////////////////////////////////////////////
public Image(Stream stream) :
base(IntPtr.Zero)
{
stream.Position = 0;
byte[] StreamData = new byte[stream.Length];
uint Read = (uint)stream.Read(StreamData, 0, StreamData.Length);
unsafe
{
fixed (byte* dataPtr = StreamData)
{
SetThis(sfImage_CreateFromMemory((char*)dataPtr, Read));
}
}
if (This == IntPtr.Zero)
throw new LoadingFailedException("image");
}
////////////////////////////////////////////////////////////
///
/// Construct the image directly from an array of pixels
///
/// 2 dimensions array containing the pixels
///
////////////////////////////////////////////////////////////
public Image(Color[,] pixels) :
base(IntPtr.Zero)
{
unsafe
{
fixed (Color* PixelsPtr = pixels)
{
uint Width = (uint)pixels.GetLength(0);
uint Height = (uint)pixels.GetLength(1);
SetThis(sfImage_CreateFromPixels(Width, Height, PixelsPtr));
}
}
if (This == IntPtr.Zero)
throw new LoadingFailedException("image");
}
////////////////////////////////////////////////////////////
///
/// Save the contents of the image to a file
///
/// Path of the file to save (overwritten if already exist)
/// True if saving was successful
////////////////////////////////////////////////////////////
public bool SaveToFile(string filename)
{
return sfImage_SaveToFile(This, filename);
}
////////////////////////////////////////////////////////////
///
/// Create a transparency mask from a specified colorkey
///
/// Color to become transparent
////////////////////////////////////////////////////////////
public void CreateMaskFromColor(Color color)
{
CreateMaskFromColor(color, 0);
}
////////////////////////////////////////////////////////////
///
/// Create a transparency mask from a specified colorkey
///
/// Color to become transparent
/// Alpha value to use for transparent pixels
////////////////////////////////////////////////////////////
public void CreateMaskFromColor(Color color, byte alpha)
{
sfImage_CreateMaskFromColor(This, color, alpha);
}
////////////////////////////////////////////////////////////
///
/// Copy pixels from another image onto this one.
/// This function does a slow pixel copy and should only
/// be used at initialization time
///
/// Source image to copy
/// X coordinate of the destination position
/// Y coordinate of the destination position
////////////////////////////////////////////////////////////
public void Copy(Image source, uint destX, uint destY)
{
sfImage_Copy(This, source.This, destX, destY, new IntRect(0, 0, 0, 0));
}
////////////////////////////////////////////////////////////
///
/// Copy pixels from another image onto this one.
/// This function does a slow pixel copy and should only
/// be used at initialization time
///
/// Source image to copy
/// X coordinate of the destination position
/// Y coordinate of the destination position
/// Sub-rectangle of the source image to copy
////////////////////////////////////////////////////////////
public void Copy(Image source, uint destX, uint destY, IntRect sourceRect)
{
sfImage_Copy(This, source.This, destX, destY, sourceRect);
}
////////////////////////////////////////////////////////////
///
/// Create the image from the current contents of the
/// given window
///
/// Window to capture
/// True if copy has been successful
////////////////////////////////////////////////////////////
public bool CopyScreen(RenderWindow window)
{
return CopyScreen(window, new IntRect(0, 0, 0, 0));
}
////////////////////////////////////////////////////////////
///
/// Create the image from the current contents of the
/// given window
///
/// Window to capture
/// Sub-rectangle of the screen to copy
/// True if copy has been successful
////////////////////////////////////////////////////////////
public bool CopyScreen(RenderWindow window, IntRect sourceRect)
{
return sfImage_CopyScreen(This, window.This, sourceRect);
}
////////////////////////////////////////////////////////////
///
/// Get a pixel from the image
///
/// X coordinate of pixel in the image
/// Y coordinate of pixel in the image
/// Color of pixel (x, y)
////////////////////////////////////////////////////////////
public Color GetPixel(uint x, uint y)
{
return sfImage_GetPixel(This, x, y);
}
////////////////////////////////////////////////////////////
///
/// Change the color of a pixel
///
/// X coordinate of pixel in the image
/// Y coordinate of pixel in the image
/// New color for pixel (x, y)
////////////////////////////////////////////////////////////
public void SetPixel(uint x, uint y, Color color)
{
sfImage_SetPixel(This, x, y, color);
}
////////////////////////////////////////////////////////////
///
/// Get a copy of the array of pixels (RGBA 8 bits integers components)
/// Array size is Width x Height x 4
///
/// Array of pixels
////////////////////////////////////////////////////////////
public byte[] Pixels
{
get
{
byte[] PixelsPtr = new byte[Width * Height * 4];
Marshal.Copy(sfImage_GetPixelsPtr(This), PixelsPtr, 0, PixelsPtr.Length);
return PixelsPtr;
}
}
////////////////////////////////////////////////////////////
///
/// Bind the image for rendering
///
////////////////////////////////////////////////////////////
public void Bind()
{
sfImage_Bind(This);
}
////////////////////////////////////////////////////////////
///
/// Control the smooth filter
///
////////////////////////////////////////////////////////////
public bool Smooth
{
get {return sfImage_IsSmooth(This);}
set {sfImage_SetSmooth(This, value);}
}
////////////////////////////////////////////////////////////
///
/// Width of the image, in pixels
///
////////////////////////////////////////////////////////////
public uint Width
{
get {return sfImage_GetWidth(This);}
}
////////////////////////////////////////////////////////////
///
/// Height of the image, in pixels
///
////////////////////////////////////////////////////////////
public uint Height
{
get {return sfImage_GetHeight(This);}
}
////////////////////////////////////////////////////////////
///
/// Internal constructor
///
/// Pointer to the object in C library
////////////////////////////////////////////////////////////
internal Image(IntPtr thisPtr) :
base(thisPtr)
{
}
////////////////////////////////////////////////////////////
///
/// Handle the destruction of the object
///
/// Is the GC disposing the object, or is it an explicit call ?
////////////////////////////////////////////////////////////
protected override void Destroy(bool disposing)
{
if (!disposing)
Context.Global.SetActive(true);
sfImage_Destroy(This);
if (!disposing)
Context.Global.SetActive(false);
}
#region Imports
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfImage_Create();
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfImage_CreateFromColor(uint Width, uint Height, Color Col);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
unsafe static extern IntPtr sfImage_CreateFromPixels(uint Width, uint Height, Color* Pixels);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfImage_CreateFromFile(string Filename);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
unsafe static extern IntPtr sfImage_CreateFromMemory(char* Data, uint Size);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfImage_Destroy(IntPtr This);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern bool sfImage_SaveToFile(IntPtr This, string Filename);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfImage_CreateMaskFromColor(IntPtr This, Color Col, byte Alpha);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern bool sfImage_CopyScreen(IntPtr This, IntPtr Window, IntRect SourceRect);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfImage_Copy(IntPtr This, IntPtr Source, uint DestX, uint DestY, IntRect SourceRect);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfImage_SetPixel(IntPtr This, uint X, uint Y, Color Col);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern Color sfImage_GetPixel(IntPtr This, uint X, uint Y);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfImage_GetPixelsPtr(IntPtr This);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfImage_Bind(IntPtr This);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern void sfImage_SetSmooth(IntPtr This, bool Smooth);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern uint sfImage_GetWidth(IntPtr This);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern uint sfImage_GetHeight(IntPtr This);
[DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity]
static extern bool sfImage_IsSmooth(IntPtr This);
#endregion
}
}
}