public static void DrawArea(this IT8951SPIDevice device, Action <DrawingBuffer> pixelOperateCallback, ushort x, ushort y, ushort width, ushort height, ImagePixelPackEnum bpp = ImagePixelPackEnum.BPP4, ImageEndianTypeEnum endian = ImageEndianTypeEnum.BigEndian, ImageRotateEnum rotate = ImageRotateEnum.Rotate0, DisplayModeEnum mode = DisplayModeEnum.GC16) { var p = new DrawingBuffer(x, y, width, height, bpp); pixelOperateCallback(p); device.LoadImageArea(bpp, endian, rotate, p.Buffer.Span, x, y, width, height); device.RefreshArea(mode, x, y, width, height); }
public static void Draw(this IT8951SPIDevice device, Action <DrawingBuffer> pixelOperateCallback, ImagePixelPackEnum bpp = ImagePixelPackEnum.BPP4, ImageEndianTypeEnum endian = ImageEndianTypeEnum.BigEndian, ImageRotateEnum rotate = ImageRotateEnum.Rotate0, DisplayModeEnum mode = DisplayModeEnum.GC16) { var p = new DrawingBuffer(device, bpp); pixelOperateCallback(p); if (bpp == ImagePixelPackEnum.BPP1) { device.LoadImageArea(ImagePixelPackEnum.BPP8, endian, rotate, p.Buffer.Span, 0, 0, (ushort)(device.DeviceInfo.ScreenSize.Width / 8), (ushort)device.DeviceInfo.ScreenSize.Height); device.Set1BPPMode(true); device.RefreshScreen(DisplayModeEnum.A2); device.Set1BPPMode(false); } else { device.LoadImage(bpp, endian, rotate, p.Buffer.Span); device.RefreshScreen(mode); } }
/// <summary> /// Partial display image from Image Object /// </summary> /// <param name="device">device to present the image</param> /// <param name="image">Image object</param> /// <param name="sourceImageArea">the area to be displayed from source image</param> /// <param name="targetPosition">the top left position to place the image of device screen</param> /// <param name="bpp">BitsPerPixel mode in pixel transfer. suggest use BPP4 for GC16 and BPP1 for A2</param> /// <param name="displayMode">Display mode, GC16=16 level greyscale, A2=Balck and White</param> /// <exception cref="ArgumentOutOfRangeException">display mode cannot be INIT and position X and width must be multiple of 32 in 1bpp mode</exception> public static void DrawImagePartial(this IT8951SPIDevice device, Image <L8> image, Rectangle sourceImageArea, Point targetPosition, ImagePixelPackEnum bpp = ImagePixelPackEnum.BPP4, DisplayModeEnum displayMode = DisplayModeEnum.GC16) { if (displayMode == DisplayModeEnum.INIT) { throw new ArgumentOutOfRangeException(nameof(displayMode), "displayMode can't be INIT while drawing image"); } if (bpp == ImagePixelPackEnum.BPP1) { if (sourceImageArea.Width % 32 != 0 || targetPosition.X % 32 != 0) { throw new ArgumentOutOfRangeException("position X and width must be multiple of 32 in 1bpp mode"); } } var p = new DrawingBuffer(targetPosition.X, targetPosition.Y, sourceImageArea.Width, sourceImageArea.Height, bpp); Parallel.For(0, sourceImageArea.Height, i => { var rowBytes = image.DangerousGetPixelRowMemory(sourceImageArea.Y + i).Span.Slice(sourceImageArea.X, sourceImageArea.Width); p.WriteRow(rowBytes, i, getByteFromL8); }); ushort x = (ushort)targetPosition.X; ushort y = (ushort)targetPosition.Y; ushort w = (ushort)sourceImageArea.Width; ushort h = (ushort)sourceImageArea.Height; if (bpp == ImagePixelPackEnum.BPP1) { //use bpp8 to transfer full bytes data device.LoadImageArea(ImagePixelPackEnum.BPP8, ImageEndianTypeEnum.BigEndian, ImageRotateEnum.Rotate0, p.Buffer.Span, (ushort)(x / 8), y, (ushort)(w / 8), h); device.Set1BPPMode(true); device.RefreshArea(displayMode, x, y, w, h); device.Set1BPPMode(false);//restore to default display mode } else { device.LoadImageArea(bpp, ImageEndianTypeEnum.BigEndian, ImageRotateEnum.Rotate0, p.Buffer.Span, x, y, w, h); device.RefreshArea(displayMode, x, y, w, h); } }
/// <summary> /// Display a full sreen image from Image Object. /// </summary> /// <param name="device">device to present the image</param> /// <param name="image"> Image object</param> /// <param name="dither">dither the image for better visual</param> /// <param name="autoResize">Resize the image if necessary. An exception will thrown if this parameter is false and image size not equal device screen size</param> /// <param name="bpp">BitsPerPixel mode in pixel transfer. suggest use BPP4 for GC16 and BPP1 for A2 </param> /// <param name="displayMode">Display mode, GC16=16 level greyscale, A2=Balck and White</param> public static void DrawImage(this IT8951SPIDevice device, Image <L8> image, bool dither = true, bool autoResize = true, ImagePixelPackEnum bpp = ImagePixelPackEnum.BPP4, DisplayModeEnum displayMode = DisplayModeEnum.GC16) { if (displayMode == DisplayModeEnum.INIT) { throw new ArgumentOutOfRangeException(nameof(displayMode), "displayMode can't be INIT while drawing image"); } if (device.DeviceInfo.ScreenSize.Width != image.Width || device.DeviceInfo.ScreenSize.Height != image.Height) { if (!autoResize) { throw new ArgumentException("image size should be same as device screen size"); } else { var o = new ResizeOptions(); o.Size = new Size(device.DeviceInfo.ScreenSize.Width, device.DeviceInfo.ScreenSize.Height); o.Mode = ResizeMode.Pad; image.Mutate(opt => { opt.Resize(o); }); } } var p = new DrawingBuffer(device, bpp); if (dither) { switch (bpp) { case ImagePixelPackEnum.BPP2: image.Mutate(opt => { Color[] palette = new Color[4]; for (int i = 0; i < palette.Length; i++) { palette[i] = new Color(new L16((ushort)(i * 16384))); } opt.Dither(KnownDitherings.FloydSteinberg, palette); }); break; case ImagePixelPackEnum.BPP3: throw new NotImplementedException(); case ImagePixelPackEnum.BPP4: //maximum grey scale is 16 levels case ImagePixelPackEnum.BPP8: //BPP8=BPP4, 4 lower bits are ignored image.Mutate(opt => { Color[] palette = new Color[16]; for (int i = 0; i < palette.Length; i++) { palette[i] = new Color(new L16((ushort)(i * 4096))); } opt.Dither(KnownDitherings.FloydSteinberg, palette); }); break; case ImagePixelPackEnum.BPP1: image.Mutate(opt => { opt.BinaryDither(KnownDitherings.FloydSteinberg); }); break; default: break; } } Parallel.For(0, image.Height, i => { var rowBytes = image.DangerousGetPixelRowMemory(i).Span; p.WriteRow(rowBytes, i, getByteFromL8); }); if (bpp == ImagePixelPackEnum.BPP1) { ushort width = (ushort)(image.Width / 8); ushort height = (ushort)(image.Height); //use bpp8 to transfer full bytes data device.LoadImageArea(ImagePixelPackEnum.BPP8, ImageEndianTypeEnum.BigEndian, ImageRotateEnum.Rotate0, p.Buffer.Span, 0, 0, width, height); device.Set1BPPMode(true); device.RefreshArea(displayMode, 0, 0, (ushort)image.Width, (ushort)image.Height); device.Set1BPPMode(false);//restore to default display mode } else { device.LoadImage(bpp, ImageEndianTypeEnum.BigEndian, ImageRotateEnum.Rotate0, p.Buffer.Span); device.RefreshScreen(displayMode); } }