namespace RemoteFrameBuffer.Common { public class RgbFrameBuffer { private RgbPixel[][] _frame; public UInt16 Width { get { return (UInt16)this._frame[0].Length; } } public UInt16 Height { get { return (UInt16)this._frame.Length; } } private static RgbPixel[][] MakeFrameBuffer(UInt16 width, UInt16 height) { RgbPixel[][] buf = new RgbPixel[height][]; for (Int32 i = 0; i < height; i++) { buf[i] = new RgbPixel[width]; } return buf; } public RgbFrameBuffer(UInt16 width, UInt16 height) { this._frame = MakeFrameBuffer(width, height); } public void SetRegion(RgbPixel[][] source, UInt16 source_x, UInt16 source_y, UInt16 width, UInt16 height, UInt16 target_x, UInt16 target_y) { for (Int32 y = 0; y < height; y++) { Array.Copy(source[y + source_y], source_x, this._frame[y + target_y], target_x, width); } } public void CopyRegion(UInt16 source_x, UInt16 source_y, UInt16 width, UInt16 height, UInt16 target_x, UInt16 target_y) => this.SetRegion(this._frame, source_x, source_y, width, height, target_x, target_y); public void SaveBitmap(String filename) { #warning Endianness is straight up ignored Int32 rowBytes = (this.Width * 3) + 3; rowBytes -= rowBytes % 4; Int32 bytes = 54 + (this.Height * rowBytes); Byte[] buf = new Byte[bytes]; buf[0] = 0x42; buf[1] = 0x4D; Array.Copy(BitConverter.GetBytes(bytes), 0, buf, 2, 4); buf[10] = 54; buf[14] = 40; Array.Copy(BitConverter.GetBytes((UInt32)this.Width), 0, buf, 18, 4); Array.Copy(BitConverter.GetBytes((UInt32)this.Height), 0, buf, 22, 4); buf[26] = 1; buf[28] = 24; Array.Copy(BitConverter.GetBytes(this.Height * rowBytes), 0, buf, 34, 4); for (Int32 j = 0; j < this.Height; j++) { Int32 off = 54 + (j * rowBytes); for (Int32 i = 0; i < this.Width; i++) { Int32 pos = off + (i * 3); buf[pos] = this._frame[this.Height - j - 1][i].Blue; buf[pos + 1] = this._frame[this.Height - j - 1][i].Green; buf[pos + 2] = this._frame[this.Height - j - 1][i].Red; } } File.WriteAllBytes(filename, buf); } } }