public void WriteData(VC_IMAGE_TYPE_T type, int pitch, byte[] data, Rectangle rect) { DISPMANX_STATUS_T ret; GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); try { VC_RECT_T vcrect = new VC_RECT_T { x = rect.X, y = rect.Y, width = rect.Width, height = rect.Height }; ret = Native.DispmanxNativeMethods.ResourceWriteData(this.m_handle, type, pitch, dataHandle.AddrOfPinnedObject(), ref vcrect); if (ret != DISPMANX_STATUS_T.SUCCESS) { throw new DispmanException($"Operation failed : {nameof(Native.DispmanxNativeMethods.ResourceWriteData)} returned {ret}"); } } finally { dataHandle.Free(); } }
static void Main(string[] args) { using (BcmHost host = new BcmHost()) using (Display disp = host.Dispman.DisplayOpen(Screen.MAIN_LCD)) { int pitch = ALIGN_UP(2 * disp.Width, 32); VC_IMAGE_TYPE_T type = VC_IMAGE_TYPE_T.VC_IMAGE_RGB565; using (Resource res = host.Dispman.CreateResource(type, disp.Width, disp.Height)) { Console.WriteLine("snapshot"); disp.Snapshot(res, DISPMANX_TRANSFORM_T.DISPMANX_NO_ROTATE); Console.WriteLine("readdata"); Rectangle rect = new Rectangle(0, 0, disp.Width, disp.Height); byte[] image = new byte[pitch * disp.Height]; res.ReadData(rect, image, disp.Width * 2); Console.WriteLine("jpg"); using (var img = Image.LoadPixelData <Bgr565>(new Span <byte>(image), rect.Width, rect.Height)) using (MemoryStream ms = new MemoryStream()) { img.SaveAsJpeg(ms); } Console.WriteLine("ok"); } } }
/// <summary> /// Create a new resource /// </summary> /// <param name="type"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public Resource CreateResource(VC_IMAGE_TYPE_T type, int width, int height) { DISPMANX_RESOURCE_HANDLE_T handle = NativeMethods.ResourceCreate(type, (uint)width, (uint)height, out IntPtr imagePtr); if (handle.Handle == IntPtr.Zero) { return(null); } return(new Resource(handle, type, imagePtr)); }
private static void FillRect(VC_IMAGE_TYPE_T type, byte[] image, short pitch, short aligned_height, short x, short y, short w, short h, short val) { short row; short col; int linePos = y * (pitch >> 1) + x; byte[] bval = BitConverter.GetBytes(val); for (row = 0; row < h; row++) { for (col = 0; col < w; col++) { Array.Copy(bval, 0, image, linePos + col, bval.Length); } linePos += (pitch >> 1); } }
public static extern DISPMANX_STATUS_T ResourceWriteDataHandle(DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type, int src_pitch, VCHI_MEM_HANDLE_T handle, uint offset, ref VC_RECT_T rect);
public static extern DISPMANX_STATUS_T ResourceWriteData(DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type, int src_pitch, IntPtr src_address, ref VC_RECT_T rect);
public static extern DISPMANX_RESOURCE_HANDLE_T ResourceCreate(VC_IMAGE_TYPE_T type, uint width, uint height, out IntPtr imagePtr);
internal Resource(DISPMANX_RESOURCE_HANDLE_T handle, VC_IMAGE_TYPE_T type, IntPtr imagePtr) { this.m_handle = handle; this.m_type = type; this.m_imagePtr = imagePtr; }
public void Run() { VC_IMAGE_TYPE_T type = VC_IMAGE_TYPE_T.VC_IMAGE_RGB565; short padded_width; short pitch; short r_x0, r_y0, r_x1, r_y1; byte[] image; byte[] back_image; pitch = ALIGN_UP((short)(2 * this.m_display.Width), (short)32); padded_width = (short)(pitch / BPP); image = new byte[pitch * this.m_display.Height]; back_image = new byte[pitch * this.m_display.Height]; r_x0 = r_y0 = 0; r_x1 = (short)this.m_display.Width; r_y1 = (short)this.m_display.Height; using (Resource resource = this.m_host.Dispman.CreateResource(type, this.m_display.Width, this.m_display.Height)) { using (RfbScreen server = new RfbScreen(null, padded_width, this.m_display.Height, 5, 3, BPP)) { throw new NotImplementedException(); //server.DumpProps(); //server.DumpPrintf(); //Console.WriteLine("width={0}", server.Width); //Console.WriteLine("paddedWidthInBytes={0}", server.PaddedWidthInBytes); //Console.WriteLine("height={0}", server.Height); //Console.WriteLine("depth={0}", server.Depth); //Console.WriteLine("bitsPerPixel={0}", server.BitsPerPixel); //Console.WriteLine("sizeInBytes={0}", server.SizeInBytes); //Console.WriteLine("blackPixel={0}", server.BlackPixel); //Console.WriteLine("whitePixel={0}", server.WhitePixel); ////Console.WriteLine("screenData={0}", server.screenData); //Console.WriteLine("desktopName={0}", server.DesktopName); //Console.WriteLine("thisHost={0}", server.ThisHost); //Console.WriteLine("autoPort={0}", server.AutoPort); //Console.WriteLine("port={0}", server.Port); //Console.WriteLine("udpPort={0}", server.UdpPort); //Console.WriteLine("deferUpdateTime={0}", server.DeferUpdateTime); //Console.WriteLine("===="); //server.DesktopName = this.GetType().Name; //Console.WriteLine("desktopName={0}", server.DesktopName); //this.m_framebuffer = Marshal.AllocHGlobal(pitch * this.m_display.Height); ////server.FrameBuffer = this.m_framebuffer; //server.AlwaysShared = true; //Console.WriteLine("rfbInitServer"); //using (var srv = server.InitServer()) //{ // Console.WriteLine("rfbInitServer ok"); // while (srv.IsActive()) // { // //if (TimeToTakePicture(server)) // //{ // // if (TakePicture()) // // { // // server.MarkRectAsModified(server, r_x0, r_y0, r_x1, r_y1); // // } // //} // //usec = server.deferUpdateTime * 1000; // //server.ProcessEvents(server, usec); // } //} } //server.frameBuffer = this.m_framebuffer = Marshal.AllocHGlobal(pitch * this.m_display.Height); //server.alwaysShared = true; //int usec = 1000; //Console.WriteLine("rfbInitServer"); //NativeMethods.rfbInitServer(server); //try //{ // Func<bool> TakePicture = () => // { // var transform = DISPMANX_TRANSFORM_T.DISPMANX_NO_ROTATE; // this.m_display.Snapshot(resource, transform); // Rectangle rect = new Rectangle(0, 0, this.m_display.Width, this.m_display.Height); // resource.ReadData(rect, image, (uint)pitch); // //TODO : detect changed area // return true; // }; // while (NativeMethods.rfbIsActive(server)) // { // if (TimeToTakePicture()) // if (TakePicture()) // NativeMethods.rfbMarkRectAsModified(server, r_x0, r_y0, r_x1, r_y1); // usec = server.deferUpdateTime * 1000; // NativeMethods.rfbProcessEvents(server, usec); // } //} //finally //{ // Console.WriteLine("rfbShutdownServer"); // NativeMethods.rfbShutdownServer(server, true); //} } }
static void Main(string[] args) { Alpha alpha = new Alpha { Flags = DISPMANX_FLAGS_ALPHA_T.DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_T.DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, Opacity = 120, Mask = null }; Screen screen = Screen.MAIN_LCD; short width = WIDTH; short height = HEIGHT; short pitch = ALIGN_UP((short)(width * 2), (short)32); short aligned_height = ALIGN_UP(height, (short)16); VC_IMAGE_TYPE_T type = VC_IMAGE_TYPE_T.VC_IMAGE_RGB565; try { using (BcmHost host = new BcmHost()) { Console.WriteLine("Open display {0}", screen); using (Display display = host.Dispman.DisplayOpen(screen)) { Console.WriteLine("Display is: {0} {1}x{2}", display.DisplayNum, display.Width, display.Height); byte[] image = new byte[pitch * height]; GCHandle imageHandle = GCHandle.Alloc(image, GCHandleType.Pinned); try { FillRect(type, image, pitch, aligned_height, 0, 0, width, height, unchecked ((short)0xFFFF)); FillRect(type, image, pitch, aligned_height, 0, 0, width, height, unchecked ((short)0xF800)); FillRect(type, image, pitch, aligned_height, 20, 20, (short)(width - 40), (short)(height - 40), unchecked ((short)0x07E0)); FillRect(type, image, pitch, aligned_height, 40, 40, (short)(width - 80), (short)(height - 80), unchecked ((short)0x001F)); } finally { imageHandle.Free(); } using (Resource resource = host.Dispman.CreateResource(type, width, height)) { Rectangle dst_rect = new Rectangle(0, 0, width, height); resource.WriteData(pitch, image, dst_rect); Update update = host.Dispman.UpdateStart(10); Rectangle src_rect = new Rectangle(0, 0, width << 16, height << 16); dst_rect = new Rectangle((display.Width - width) / 2, (display.Height - height) / 2, width, height); Element element = host.Dispman.ElementAdd(update, display, 2000 /*layer*/, dst_rect, resource, src_rect, Protection.None, alpha, null /*clamp*/, DISPMANX_TRANSFORM_T.DISPMANX_NO_ROTATE); update.SubmitSync(); Console.WriteLine("Sleeping for 10 seconds..."); Thread.Sleep(TimeSpan.FromSeconds(10)); update = host.Dispman.UpdateStart(10); host.Dispman.ElementRemove(update, element); update.SubmitSync(); } } } } catch (Exception ex) { Console.WriteLine(ex.GetType().FullName + ": " + ex.Message); Console.WriteLine(ex.StackTrace); } }