/// <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(); }
/// <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(); }
public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size) { if (bmp == null) { return; } bmp.Lock(); int sizesize = size * size; LineSegment linesegment = new LineSegment(from, to); 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); Int32 *start = (Int32 *)bmp.BackBuffer.ToPointer(); start += segmentbounds.Left; 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; } pixel++; } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
/// <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(); }
/// <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(); }
public static unsafe void Test2(WriteableBitmap bmp, Point from, Point to, Color color, int size) { Random r = new Random(); AirbrushDots = 500; AirbrushDotRadius = 2; if (bmp == null) { return; } bmp.Lock(); // Create a line segment representation LineSegment segment = new LineSegment(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 + AirbrushDotRadius); segmentbounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushDotRadius); 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; //세로로 rainbow if (i < 50) { if ((i % 5) == 0) { color = Colors.Red; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Red; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Red; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Red; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Red; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 50 && i < 100) { if ((i % 5) == 0) { color = Colors.Orange; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Orange; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Orange; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Orange; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Orange; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 100 && i < 150) { if ((i % 5) == 0) { color = Colors.Yellow; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Yellow; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Yellow; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Yellow; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Yellow; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 150 && i < 200) { if ((i % 5) == 0) { color = Colors.Green; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Green; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Green; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Green; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Green; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 200 && i < 250) { if ((i % 5) == 0) { color = Colors.Blue; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Blue; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Blue; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Blue; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Blue; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 250 && i < 300) { if ((i % 5) == 0) { color = Colors.Indigo; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Indigo; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Indigo; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Indigo; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Indigo; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 300 && i < 350) { if ((i % 5) == 0) { color = Colors.BlueViolet; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.BlueViolet; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.BlueViolet; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.BlueViolet; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.BlueViolet; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushDotRadius); 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(AirbrushDotKernel[row][col], color.R, color.G, color.B)); } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point?previous, Color color, int size) { if (bmp == null) { return; } bmp.Lock(); int sizesize = size * size; uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B; LineSegment linesegment = new LineSegment(from, to); 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); UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); start += segmentbounds.Left; if (previous.HasValue) { LineSegment previoussegment = new LineSegment(previous.Value, from); 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); } } pixel++; } } } else { 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); } } pixel++; } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
public static unsafe void Test4(WriteableBitmap bmp, Point from, Point to, Color color, int size) { AirbrushDots = 1000; AirbrushDotRadius = 4; if (bmp == null) { return; } bmp.Lock(); // Create a line segment representation LineSegment segment = new LineSegment(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 + 500 + AirbrushDotRadius); segmentbounds.AddPoint((int)to.X, (int)to.Y, size + 500 + AirbrushDotRadius); 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 =size; //double angle =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 by = y; if (i % 4 == 0) { bx = x + 500; by = y + 500; } else if (i % 4 == 1) { bx = x - 500; by = y + 500; } else if (i % 4 == 2) { bx = x + 500; by = y - 500; } else if (i % 4 == 3) { bx = x - 500; by = y - 500; } //switch (i % 4) //{ // case 0: // bx= //} BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushDotRadius); 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(AirbrushDotKernel[row][col], color.R, color.G, color.B)); } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
public static unsafe void Butterfly(WriteableBitmap bmp, Point from, Point to, Color color, int size) { AirbrushDots = 2000; AirbrushDotRadius = 3; Random r = new Random(); if (bmp == null) { return; } bmp.Lock(); // Create a line segment representation LineSegment segment = new LineSegment(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, 1500); segmentbounds.AddPoint((int)to.X, (int)to.Y, 1500); segmentbounds.Clip(bitmapbounds); UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); int stride = bmp.BackBufferStride / sizeof(UInt32); // Move from 'from' to 'to' along timestep0 intervals, with one dot painted per interval int ran; if (size < 10) { ran = (r.Next() % (300 - size * 20)) + 1; } else if (size < 20) { ran = (r.Next() % (450 - size * 20)) + 1; } else if (size < 30) { ran = (r.Next() % (600 - size * 30)) + 1; } else if (size < 40) { ran = (r.Next() % (1400 - size * 20)) + 1; } else { ran = (r.Next() % (3200 - size * 20)) + 1; } for (int i = 0; i < AirbrushDots; i++) { int x, y; temp = i; segment.Interpolate(i, AirbrushDots, out x, out y); int bx = x + temp; int by = y - (temp * temp) / ran; if (temp % 4 == 0) { if (ran % 2 == 0) { bx = x + (temp * temp) / ran; by = y - temp; } else { bx = x + temp; by = y - (temp * temp) / ran; } } else if (temp % 4 == 1) { if (ran % 2 == 0) { bx = x + (temp * temp) / ran; by = y + temp; } else { bx = x + temp; by = y + (temp * temp) / ran; } } else if (temp % 4 == 2) { if (ran % 2 == 0) { bx = x - (temp * temp) / ran; by = y + temp; } else { bx = x - temp; by = y + (temp * temp) / ran; } } else if (temp % 4 == 3) { if (ran % 2 == 0) { bx = x - (temp * temp) / ran; by = y - temp; } else { bx = x - temp; by = y - (temp * temp) / ran; } } if (Math.Sqrt((bx - x) * (bx - x) + (by - y) * (by - y)) > size * 10) { continue; } BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushDotRadius); 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(AirbrushDotKernel[row][col], color.R, color.G, color.B)); } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }