Advertisement
bobmarley12345

C#/C++ interop pixel drawing

Jan 8th, 2023 (edited)
1,183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.05 KB | None | 0 0
  1. // XAML WPF code
  2. <Grid>
  3.     <Border Width="502" Height="502" BorderThickness="1" BorderBrush="Red">
  4.         <Image x:Name="Img" Width="500" Height="500"/>
  5.     </Border>
  6. </Grid>
  7.  
  8. // C# Code
  9.  
  10. private readonly WriteableBitmap bitmap;
  11.  
  12. public MainWindow() {
  13.     InitializeComponent();
  14.     this.Img.Source = this.bitmap = new WriteableBitmap(500, 500, 96d, 96d, PixelFormats.Bgr24, null);
  15.     this.Img.MouseMove += this.Img_MouseMove;
  16. }
  17.  
  18. private void Img_MouseMove(object sender, MouseEventArgs e) {
  19.     unsafe {
  20.         const int w = 5, h = 5;
  21.         Point p = e.GetPosition(this.Img);
  22.         if (p.X <= (500 - w) && p.Y <= (500 - h)) {
  23.             this.bitmap.Lock();
  24.             DrawRectangleFast(this.bitmap, (int) p.X, (int) p.Y, w, h, Colors.Red);
  25.             this.bitmap.Unlock();
  26.         }
  27.     }
  28. }
  29.  
  30. public readonly struct COLOUR {
  31.     public readonly byte r;
  32.     public readonly byte g;
  33.     public readonly byte b;
  34.  
  35.     public COLOUR(byte r, byte g, byte b) {
  36.         this.r = r;
  37.         this.g = g;
  38.         this.b = b;
  39.     }
  40. }
  41.  
  42. [DllImport("../../../Debug/FrameControl.Native.dll", CallingConvention = CallingConvention.Cdecl)]
  43. public static extern void draw_pixel(IntPtr backBuf, int bbpx, int stride, int l, int t, int w, int h, COLOUR colour);
  44.  
  45. public static void DrawRectangleFast(WriteableBitmap bitmap, int left, int top, int width, int height, Color color) {
  46.     draw_pixel(bitmap.BackBuffer, bitmap.Format.BitsPerPixel / 8, bitmap.BackBufferStride, left, top, width, height, new COLOUR(color.R, color.G, color.B));
  47.     bitmap.AddDirtyRect(new Int32Rect(left, top, width, height));
  48. }
  49.  
  50. // C++ Lib Side
  51. //   Transformed code a bit with the help of this post:
  52. //   https://stackoverflow.com/questions/443867/drawing-pixels-in-wpf
  53.  
  54. #define EXPORT _declspec(dllexport)
  55.  
  56. #include <stdint.h>
  57.  
  58. struct COLOUR {
  59.     uint8_t r;
  60.     uint8_t g;
  61.     uint8_t b;
  62. };
  63.  
  64. extern "C" {
  65.     EXPORT void draw_pixel(uint8_t* bbuf, int bytePerPx, int stride, int left, int top, int w, int h, COLOUR col) {
  66.         // Compute the pixel's color
  67.         int colorData = col.r << 16; // R
  68.         colorData |= col.g << 8; // G
  69.         colorData |= col.b << 0; // B
  70.         for (int y = 0; y < h; y++) {
  71.             // Get a pointer to the back buffer
  72.  
  73.             // int* would not work for some reason
  74.            
  75.             // this could also be type char* or int. It cannot be a non-byte pointer, because
  76.             // the offset calculations done below this line are byte-based, meaning the
  77.             // compiler will include the size of the type in the offset calclations.
  78.             uint8_t* pBackBuffer = bbuf;
  79.  
  80.             // Find the address of the pixel to draw
  81.             pBackBuffer += (top + y) * stride;
  82.             pBackBuffer += left * bytePerPx;
  83.  
  84.             for (int x = 0; x < w; x++) {
  85.                 // Assign the color data to the pixel
  86.                 *(int*) pBackBuffer = colorData;
  87.                 // Increment the address of the pixel to draw
  88.                 pBackBuffer += bytePerPx;
  89.             }
  90.         }
  91.     }
  92. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement