Paints on a WriteableBitmap like a paintbrush - CSharp System.Windows.Media.Imaging

CSharp examples for System.Windows.Media.Imaging:WriteableBitmap

Description

Paints on a WriteableBitmap like a paintbrush

Demo Code

// (c) Copyright Microsoft Corporation.
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.IO;/*from w w w.  j  a v  a 2 s .  com*/
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System;

public class Main{
        /// <summary>
        /// Paints on a pbgra32 WriteableBitmap like a paintbrush
        /// </summary>
        /// <param name="bmp">The bitmap to modify</param>
        /// <param name="from">The starting point of the stroke</param>
        /// <param name="to">The end point of the stroke</param>
        /// <param name="previous">The point prior to the 'from' point, or null</param>
        /// <param name="color">The color of the brush</param>
        /// <param name="size">The stroke size</param>
        public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point? previous, Color color, int size)
        {
            if (bmp == null) return;

            bmp.Lock();

            // Intermediate storage of the square of the size
            int sizesize = size * size;
            uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B;

            // Create a line segment representation to compare distance to
            LineSegment linesegment = new LineSegment(from, to);

            // Get a bounding box for the line segment
            BoundingBox bitmapbounds = new BoundingBox();
            BoundingBox segmentbounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            segmentbounds.AddPoint((int)from.X, (int)from.Y, size);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, size);
            segmentbounds.Clip(bitmapbounds);

            // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format)
            UInt32* start = (UInt32*)bmp.BackBuffer.ToPointer();

            // Move the starting pixel to the x offset
            start += segmentbounds.Left;

            if (previous.HasValue)
            {
                LineSegment previoussegment = new LineSegment(previous.Value, from);

                // Loop through the relevant portion of the image and figure out which pixels need to be erased
                for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++)
                {
                    UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y;

                    for (int x = segmentbounds.Left; x < segmentbounds.Right; x++)
                    {
                        if (linesegment.DistanceSquared(x, y) <= sizesize && previoussegment.DistanceSquared(x, y) > sizesize)
                        {
                            if (color.A == 255)
                                *pixel = flatcolor;
                            else
                                WriteAlphaBlended(pixel, color);
                        }

                        // Move to the next pixel
                        pixel++;
                    }
                }
            }
            else
            {
                // Loop through the relevant portion of the image and figure out which pixels need to be erased
                for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++)
                {
                    UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y;

                    for (int x = segmentbounds.Left; x < segmentbounds.Right; x++)
                    {
                        if (linesegment.DistanceSquared(x, y) <= sizesize)
                        {
                            if (color.A == 255)
                                *pixel = flatcolor;
                            else
                                WriteAlphaBlended(pixel, color);
                        }

                        // Move to the next pixel
                        pixel++;
                    }
                }
            }

            bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height));
            bmp.Unlock();
        }
}

Related Tutorials