# Eraser tool for GIF editor

I am making a GIF editor in C#, and I am currently working on the eraser tool. I am not sure what I can do to make it more efficient, because when I make the thickness (diameter) more than 30 (pixels) it starts to get a bit slow.

if (click && eraserSelected)
{
{
Application.Current.Dispatcher.Invoke((Action)(() => b = imageBox.Source as WriteableBitmap));
Application.Current.Dispatcher.Invoke((Action)(() => endPoint = Mouse.GetPosition(imageBox)));

System.Windows.Media.Color color;
System.Windows.Point[] linePixels = FindPixels.Line(startPoint, endPoint).ToArray();
int[][][] pixels = new int[linePixels.Length][][];

for (int i = 0; i < linePixels.Length; i++)
pixels[i] = FindPixels.Circle(thickness, (int)linePixels[i].X, (int)linePixels[i].Y);

Bitmap originalFrame = gifFrames.GetOriginalFrame();

Application.Current.Dispatcher.Invoke((() =>
{
for (int j = 0; j < pixels.Length; j++)
for (int i = 0; i < pixels[j][0].Length; i++)
if (pixels[j][0][i] < pixelsEdited[0].Count() && pixels[j][0][i] >= 0 && pixels[j][1][i] < pixelsEdited.Count() && pixels[j][1][i] >= 0)
if (!pixelsEdited[pixels[j][1][i]][pixels[j][0][i]])
{
color = System.Windows.Media.Color.FromRgb(originalFrame.GetPixel(pixels[j][0][i], pixels[j][1][i]).R, originalFrame.GetPixel(pixels[j][0][i], pixels[j][1][i]).G, originalFrame.GetPixel(pixels[j][0][i], pixels[j][1][i]).B);
try
{
b.SetPixel(pixels[j][0][i], pixels[j][1][i], color);
pixelsEdited[pixels[j][1][i]][pixels[j][0][i]] = true;
}
catch { }
}
}));

Application.Current.Dispatcher.Invoke((Action)(() => startPoint = endPoint));
}).Start();
}


That is the code for the eraser tool itself. Here is the code for the FindPixels.Line() and FindPixels.Circle() functions:

class FindPixels
{
/// <summary>
/// Finds all the pixels that are within a circle of a given diameter, and center
/// </summary>
/// <param name="diameter"></param>
/// <param name="centerX"></param>
/// <param name="centerY"></param>
/// <returns>All the pixels within a circle</returns>
public static int[][] Circle(int diameter, int centerX, int centerY)
{
int radius = diameter / 2;
List<int> pixelsX = new List<int>();
List<int> pixelsY = new List<int>();

for (int x = centerX - radius; x < centerX + radius; x++)
{
for (int y = centerY - radius; y < centerY + radius; y++)
{
double dx = x - centerX;
double dy = y - centerY;
double distanceSquared = dx * dx + dy * dy;

{
int distance = y - (centerY - radius);
for (int i = 0; i < diameter - distance * 2; i++)
{
}
break;
}
}
}

int[][] pixels = { pixelsX.ToArray(), pixelsY.ToArray() };
return pixels;
}

/// <summary>
/// Finds all pixels that form a line
/// </summary>
/// <param name="startPoint"></param>
/// <param name="endPoint"></param>
/// <returns>All points within the two points given</returns>
public static List<Point> Line(Point p0, Point p1)
{
int x0 = (int)p0.X;
int y0 = (int)p0.Y;
int x1 = (int)p1.X;
int y1 = (int)p1.Y;
int dx = Math.Abs(x1 - x0);
int dy = Math.Abs(y1 - y0);

int sx = x0 < x1 ? 1 : -1;
int sy = y0 < y1 ? 1 : -1;

int err = dx - dy;

var points = new List<Point>();

while (true)
{
if (x0 == x1 && y0 == y1) break;

int e2 = 2 * err;
if (e2 > -dy)
{
err = err - dy;
x0 = x0 + sx;
}
if (e2 < dx)
{
err = err + dx;
y0 = y0 + sy;
}
}

return points;
}
}


What I was thinking was instead of drawing a bunch of circles on each pixel of the line, I draw the start and end point and then do a rectangle to connect them, but how would I find the points connecting them.

Here is a picture of what I mean:

The red points are what I am having trouble finding, and all the points withing the pink outline are what I would change.

• Nice drawing! If that method is indeed more efficient and a reviewer happens to suggest it and even give you some code for it, that's great - but by asking on this site you're asking for feedback on any & all aspects of the code you're posting, not the code you would have liked to write and put up for review. Does your code work as intended? – Mathieu Guindon Apr 4 '16 at 2:14

It looks like your code is inefficient because you are trying to do a lot of low-level work yourselves instead of relying on existing functionality available in .NET framework, which is most likely optimized for low-level work. Here are the classes/methods I would try:

• System.Drawing.Graphics.FromImage(bitmap) method to create a Graphics object which provides methods to draw on a bitmap;
• System.Drawing.Drawing2D.GraphicsPath object to define the shape which you drawn in your question;
• System.Drawing.Graphics.FillPath(Brush, GraphicsPath) to fill the shape needed.

Defining the shape drawn is a pretty simple trigonometric exercise: you have coordinates of your starting and ending circles (x1,y1 and x2,y2), and a bunch of similar right triangles. Here is the calculation of your points:

var alpha = Math.Atan2(startPoint.Y - endPoint.Y, endPoint.X - startPoint.X); //measuring angle from X axis in clockwise direction


What you need to complete is to define a GraphicsPath which consists of 2 180-degree arcs and 2 lines, and pass it to Graphics.FillPath method