Example #1
0
        /// <summary>
        /// Paints on a WriteableBitmap with a stylized airbrush
        /// </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="color">The color of the stroke</param>
        /// <param name="size">The size of the stroke</param>
        public static unsafe void Airbrush(WriteableBitmap bmp, Point from, Point to, Color color, int size)
        {
            Random r = new Random();

            if (bmp == null) return;

            bmp.Lock();

            // Create a line segment representation
            MyLine line = new MyLine(from, to);

            // Get a bounding box for the painted area
            BoundingBox bitmapbounds = new BoundingBox();
            BoundingBox linebounds = new BoundingBox();

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

            linebounds.AddPoint((int)from.X, (int)from.Y, size + AirbrushRadiu);
            linebounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushRadiu);
            linebounds.Clip(bitmapbounds);

            UInt32* start = (UInt32*)bmp.BackBuffer.ToPointer();
            int stride = bmp.BackBufferStride / sizeof(UInt32);
            // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval
            for (int i = 0; i < AirbrushDots; i++)
            {
                int x, y;
                line.Interpolate(i, AirbrushDots, out x, out y);

                int dist = r.Next() % size;
                double angle = r.NextDouble() * 2 * Math.PI;

                double dx = Math.Cos(angle) * dist;
                double dy = Math.Sqrt(dist * dist - dx * dx);
                if (angle > Math.PI) dy = -dy;

                int bx = x + (int)dx;
                int by = y + (int)dy;

                BoundingBox dotbounds = new BoundingBox();

                dotbounds.AddPoint(bx, by, AirbrushRadiu);
                dotbounds.Clip(bitmapbounds);

                for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++)
                    for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++)
                        AlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushBytes[row][col], color.R, color.G, color.B));
            }

            bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height));
            bmp.Unlock();
        }
Example #2
0
        /// <summary>
        /// Paints on a pbgra32 WriteableBitmap with a stylized airbrush
        /// </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="color">The color of the stroke</param>
        /// <param name="size">The size of the stroke</param>
        public static unsafe void Airbrush(WriteableBitmap bmp, Point from, Point to, Color color, int size)
        {
            Random r = new Random();

            if (bmp == null)
            {
                return;
            }

            bmp.Lock();

            // Create a line segment representation
            MyLine segment = new MyLine(from, to);

            // Get a bounding box for the painted area
            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 + AirbrushRadio);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushRadio);
            segmentbounds.Clip(bitmapbounds);

            UInt32 *start  = (UInt32 *)bmp.BackBuffer.ToPointer();
            int     stride = bmp.BackBufferStride / sizeof(UInt32);

            // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval
            for (int i = 0; i < AirbrushDots; i++)
            {
                int x, y;
                segment.Interpolate(i, AirbrushDots, out x, out y);

                int    dist  = r.Next() % size;
                double angle = r.NextDouble() * 2 * Math.PI;

                double dx = Math.Cos(angle) * dist;
                double dy = Math.Sqrt(dist * dist - dx * dx);
                if (angle > Math.PI)
                {
                    dy = -dy;
                }

                int bx = x + (int)dx;
                int by = y + (int)dy;

                BoundingBox dotbounds = new BoundingBox();

                dotbounds.AddPoint(bx, by, AirbrushRadio);
                dotbounds.Clip(bitmapbounds);

                for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++)
                {
                    for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++)
                    {
                        WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushBytes[row][col], color.R, color.G, color.B));
                    }
                }
            }

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