using System;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Drawing;
namespace Raw2Picture
{
public class PictureBuffer
{
private uint[] ints;
private GCHandle handle;
private Bitmap bitmap;
public PictureBuffer(int bufferWidth, int bufferHeight)
{
AllocateBitmap(bufferWidth, bufferHeight);
}
public void AllocateBitmap(int width, int height)
{
if (Width == width && Height == height)
{
return;
}
DisposeBitmap();
if (width == 0 || height == 0)
{
return;
}
// 4 bytes per pixel, format: ARGB
ints = new uint[width * height];
// if not pinned the GC can move around the array
handle = GCHandle.Alloc(ints, GCHandleType.Pinned);
IntPtr pointer = Marshal.UnsafeAddrOfPinnedArrayElement(ints, 0);
bitmap = new Bitmap(width, height, width * 4, PixelFormat.Format32bppPArgb, pointer);
}
public void Dispose()
{
DisposeBitmap();
}
private void DisposeBitmap()
{
if (bitmap != null)
{
handle.Free();
bitmap.Dispose();
bitmap = null;
ints = null;
}
}
/// <summary>
/// A bitmap that can be rendered upon, or rendered to another graphics.
/// </summary>
public Bitmap Bitmap
{
get { return bitmap; }
}
/// <summary>Width of <see cref="Bitmap"/>.</summary>
public int Width
{
get { return bitmap == null ? 0 : bitmap.Width; }
}
/// <summary>Height of <see cref="Bitmap"/>.</summary>
public int Height
{
get { return bitmap == null ? 0 : bitmap.Height; }
}
/// <summary>
/// The integers that make up the pixels in <see cref="Bitmap"/>. The
/// pixels can be modified directly by modifying this array.
/// The pixels must contain premuliplied ARGB: R, G, and B
/// components cannot be larger than the A component.
/// </summary>
public uint[] Integers
{
get { return ints; }
}
}
}