/// <summary> /// Erases paint on a pbgra32 WriteableBitmap /// </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="size">The stroke size</param> public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size) { if (bmp == null) { return; } bmp.Lock(); // Intermediate storage of the square of the size int sizesize = size * size; // Create a line segment representation to compare distance to MyLine linesegment = new MyLine(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) Int32 *start = (Int32 *)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += segmentbounds.Left; // 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++) { Int32 *pixel = start + bmp.BackBufferStride / sizeof(Int32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize) { *pixel = 0; } // Move to the next pixel pixel++; } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
/// <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 MyLine linesegment = new MyLine(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) { MyLine previoussegment = new MyLine(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(); }
/// <summary> /// Erases paint on a WriteableBitmap /// </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="size">The stroke size</param> public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size) { if (bmp == null) return; bmp.Lock(); // Intermediate storage of the square of the size int area = size * size; // Create a line segment representation to compare distance to MyLine line = new MyLine(from, to); // Get a bounding box for the line segment 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); linebounds.AddPoint((int)to.X, (int)to.Y, size); linebounds.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) Int32* start = (Int32*)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += linebounds.Left; // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = linebounds.Top; y < linebounds.Bottom; y++) { Int32* pixel = start + bmp.BackBufferStride / sizeof(Int32) * y; for (int x = linebounds.Left; x < linebounds.Right; x++) { if (line.DistanceSquared(x, y) <= area) *pixel = 0; // Move to the next pixel pixel++; } } bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height)); bmp.Unlock(); }
/// <summary> /// Paints on a 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 area = 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 MyLine line = new MyLine(from, to); // Get a bounding box for the line segment 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); linebounds.AddPoint((int)to.X, (int)to.Y, size); linebounds.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 += linebounds.Left; if (previous.HasValue) { MyLine previoussegment = new MyLine(previous.Value, from); // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = linebounds.Top; y < linebounds.Bottom; y++) { UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = linebounds.Left; x < linebounds.Right; x++) { if (line.DistanceSquared(x, y) <= area && previoussegment.DistanceSquared(x, y) > area) { if (color.A == 255) *pixel = flatcolor; else AlphaBlended(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 = linebounds.Top; y < linebounds.Bottom; y++) { UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = linebounds.Left; x < linebounds.Right; x++) { if (line.DistanceSquared(x, y) <= area) { if (color.A == 255) *pixel = flatcolor; else AlphaBlended(pixel, color); } // Move to the next pixel pixel++; } } } bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height)); bmp.Unlock(); }