Drawing Pixels in WPF

后端 未结 5 901
日久生厌
日久生厌 2020-12-01 06:37

how would I manage pixel-by-pixel rendering in WPF (like, say, for a raytracer)? My initial guess was to create a BitmapImage, modify the buffer, and display that in an Imag

5条回答
  •  佛祖请我去吃肉
    2020-12-01 06:56

    Here's a method using WritableBitmap.

    public void DrawRectangle(WriteableBitmap writeableBitmap, int left, int top, int width, int height, Color color)
    {
        // Compute the pixel's color
        int colorData = color.R << 16; // R
        colorData |= color.G << 8; // G
        colorData |= color.B << 0; // B
        int bpp = writeableBitmap.Format.BitsPerPixel / 8;
    
        unsafe
        {
            for (int y = 0; y < height; y++)
            {
                // Get a pointer to the back buffer
                int pBackBuffer = (int)writeableBitmap.BackBuffer;
    
                // Find the address of the pixel to draw
                pBackBuffer += (top + y) * writeableBitmap.BackBufferStride;
                pBackBuffer += left * bpp;
    
                for (int x = 0; x < width; x++)
                {
                    // Assign the color data to the pixel
                    *((int*)pBackBuffer) = colorData;
    
                    // Increment the address of the pixel to draw
                    pBackBuffer += bpp;
                }
            }
        }
    
        writeableBitmap.AddDirtyRect(new Int32Rect(left, top, width, height));
    }
    

    And to use it:

    private WriteableBitmap bitmap = new WriteableBitmap(1100, 1100, 96d, 96d, PixelFormats.Bgr24, null);
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        int size = 10;
    
        Random rnd = new Random(DateTime.Now.Millisecond);
        bitmap.Lock(); // Lock() and Unlock() could be moved to the DrawRectangle() method. Just do some performance tests.
    
        for (int y = 0; y < 99; y++)
        {
            for (int x = 0; x < 99; x++)
            {
                byte colR = (byte)rnd.Next(256);
                byte colG = (byte)rnd.Next(256);
                byte colB = (byte)rnd.Next(256);
    
                DrawRectangle(bitmap, (size + 1) * x, (size + 1) * y, size, size, Color.FromRgb(colR, colG, colB));
            }
        }
    
        bitmap.Unlock(); // Lock() and Unlock() could be moved to the DrawRectangle() method. Just do some performance tests.
    
      image.Source = bitmap; // This should be done only once
    }
    

提交回复
热议问题