/// <summary> /// 计算两点之间的距离 /// </summary> /// <param name="anotherPoint">Point to calculate distance to.</param> /// <returns>Returns Euclidean distance between this point and /// <paramref name="anotherPoint"/> points.</returns> public float DistanceTo(IntPoint anotherPoint) { int dx = X - anotherPoint.X; int dy = Y - anotherPoint.Y; return (float)System.Math.Sqrt(dx * dx + dy * dy); }
// Copy constructur internal Blob(Blob source) { // copy everything except image id = source.id; rect = source.rect; cog = source.cog; area = source.area; fullness = source.fullness; colorMean = source.colorMean; colorStdDev = source.colorStdDev; }
/// <summary> /// Subtracts the specified point1. /// </summary> /// <param name="point1">The point1.</param> /// <param name="point2">The point2.</param> /// <returns></returns> public static IntPoint Subtract(IntPoint point1, IntPoint point2) { return new IntPoint(point1.X - point2.X, point1.Y - point2.Y); }
/// <summary> /// Adds the specified point1. /// </summary> /// <param name="point1">The point1.</param> /// <param name="point2">The point2.</param> /// <returns></returns> public static IntPoint Add(IntPoint point1, IntPoint point2) { return new IntPoint(point1.X + point2.X, point1.Y + point2.Y); }
/// <summary> /// Divides the specified point. /// </summary> /// <param name="point">The point.</param> /// <param name="factor">The factor.</param> /// <returns></returns> public static IntPoint Divide(IntPoint point, int factor) { return new IntPoint(point.X / factor, point.Y / factor); }
/// <summary> /// Subtracts the specified point. /// </summary> /// <param name="point">The point.</param> /// <param name="valueToSubtract">The value to subtract.</param> /// <returns></returns> public static IntPoint Subtract(IntPoint point, int valueToSubtract) { return new IntPoint(point.X - valueToSubtract, point.Y - valueToSubtract); }
/// <summary> /// Multiplies the specified point. /// </summary> /// <param name="point">The point.</param> /// <param name="factor">The factor.</param> /// <returns></returns> public static IntPoint Multiply(IntPoint point, int factor) { return new IntPoint(point.X * factor, point.Y * factor); }
// Check end point and make sure it is in the image private static void CheckEndPoint(int width, int height, IntPoint start, ref IntPoint end) { if (end.X >= width) { int newEndX = width - 1; double c = (double)(newEndX - start.X) / (end.X - start.X); end.Y = (int)(start.Y + c * (end.Y - start.Y)); end.X = newEndX; } if (end.Y >= height) { int newEndY = height - 1; double c = (double)(newEndY - start.Y) / (end.Y - start.Y); end.X = (int)(start.X + c * (end.X - start.X)); end.Y = newEndY; } if (end.X < 0) { double c = (double)(0 - start.X) / (end.X - start.X); end.Y = (int)(start.Y + c * (end.Y - start.Y)); end.X = 0; } if (end.Y < 0) { double c = (double)(0 - start.Y) / (end.Y - start.Y); end.X = (int)(start.X + c * (end.X - start.X)); end.Y = 0; } }
/// <summary> /// Adds the specified point. /// </summary> /// <param name="point">The point.</param> /// <param name="valueToAdd">The value to add.</param> /// <returns></returns> public static IntPoint Add(IntPoint point, int valueToAdd) { return new IntPoint(point.X + valueToAdd, point.Y + valueToAdd); }
/// <summary> /// Draw a line on the specified image. /// </summary> /// /// <param name="image">Source image to draw on.</param> /// <param name="point1">The first point to connect.</param> /// <param name="point2">The second point to connect.</param> /// <param name="color">Line's color.</param> /// /// <exception cref="UnsupportedImageFormatException">The source image has incorrect pixel format.</exception> /// public static unsafe void Line(UnmanagedImage image, IntPoint point1, IntPoint point2, Color color) { // TODO: faster line drawing algorithm may be implemented with integer math CheckPixelFormat(image.PixelFormat); int pixelSize = System.Drawing.Image.GetPixelFormatSize(image.PixelFormat) / 8; // image dimension int imageWidth = image.Width; int imageHeight = image.Height; int stride = image.Stride; // check if there is something to draw if ( ((point1.X < 0) && (point2.X < 0)) || ((point1.Y < 0) && (point2.Y < 0)) || ((point1.X >= imageWidth) && (point2.X >= imageWidth)) || ((point1.Y >= imageHeight) && (point2.Y >= imageHeight))) { // nothing to draw return; } CheckEndPoint(imageWidth, imageHeight, point1, ref point2); CheckEndPoint(imageWidth, imageHeight, point2, ref point1); // check again if there is something to draw if ( ((point1.X < 0) && (point2.X < 0)) || ((point1.Y < 0) && (point2.Y < 0)) || ((point1.X >= imageWidth) && (point2.X >= imageWidth)) || ((point1.Y >= imageHeight) && (point2.Y >= imageHeight))) { // nothing to draw return; } int startX = point1.X; int startY = point1.Y; int stopX = point2.X; int stopY = point2.Y; // compute pixel for grayscale image byte gray = 0; if (image.PixelFormat == PixelFormat.Format8bppIndexed) { gray = (byte)(0.2125 * color.R + 0.7154 * color.G + 0.0721 * color.B); } // draw the line int dx = stopX - startX; int dy = stopY - startY; if (Math.Abs(dx) >= Math.Abs(dy)) { // the line is more horizontal, we'll plot along the X axis float slope = (dx != 0) ? (float)dy / dx : 0; int step = (dx > 0) ? 1 : -1; // correct dx so last point is included as well dx += step; if (image.PixelFormat == PixelFormat.Format8bppIndexed) { // grayscale image for (int x = 0; x != dx; x += step) { int px = startX + x; int py = (int)((float)startY + (slope * (float)x)); byte* ptr = (byte*)image.ImageData.ToPointer() + py * stride + px; *ptr = gray; } } else { // color image for (int x = 0; x != dx; x += step) { int px = startX + x; int py = (int)((float)startY + (slope * (float)x)); byte* ptr = (byte*)image.ImageData.ToPointer() + py * stride + px * pixelSize; ptr[RGB.R] = color.R; ptr[RGB.G] = color.G; ptr[RGB.B] = color.B; } } } else { // the line is more vertical, we'll plot along the y axis. float slope = (dy != 0) ? (float)dx / dy : 0; int step = (dy > 0) ? 1 : -1; // correct dy so last point is included as well dy += step; if (image.PixelFormat == PixelFormat.Format8bppIndexed) { // grayscale image for (int y = 0; y != dy; y += step) { int px = (int)((float)startX + (slope * (float)y)); int py = startY + y; byte* ptr = (byte*)image.ImageData.ToPointer() + py * stride + px; *ptr = gray; } } else { // color image for (int y = 0; y != dy; y += step) { int px = (int)((float)startX + (slope * (float)y)); int py = startY + y; byte* ptr = (byte*)image.ImageData.ToPointer() + py * stride + px * pixelSize; ptr[RGB.R] = color.R; ptr[RGB.G] = color.G; ptr[RGB.B] = color.B; } } } }
/// <summary> /// Draw a line on the specified image. /// </summary> /// /// <param name="imageData">Source image data to draw on.</param> /// <param name="point1">The first point to connect.</param> /// <param name="point2">The second point to connect.</param> /// <param name="color">Line's color.</param> /// /// <exception cref="UnsupportedImageFormatException">The source image has incorrect pixel format.</exception> /// public static unsafe void Line(BitmapData imageData, IntPoint point1, IntPoint point2, Color color) { Line(new UnmanagedImage(imageData), point1, point2, color); }
/// <summary> /// 设置指定像素点的颜色 /// </summary> /// <param name="point">Point's coordiates to set color for.</param> /// <param name="color">Color to set for the pixel.</param> /// <remarks><para><note>For images having 16 bpp per color plane, the method extends the specified color /// value to 16 bit by multiplying it by 256.</note></para></remarks> public void SetPixel(IntPoint point, Color color) { SetPixel(point.X, point.Y, color); }
/// <summary> /// Draw a line on the specified image. /// </summary> /// /// <param name="image">Source image to draw on.</param> /// <param name="point1">The first point to connect.</param> /// <param name="point2">The second point to connect.</param> /// <param name="color">Line's color.</param> /// /// <exception cref="UnsupportedImageFormatException">The source image has incorrect pixel format.</exception> /// public static unsafe void Line(UnmanagedImage image, IntPoint point1, IntPoint point2, Color color) { // TODO: faster line drawing algorithm may be implemented with integer math CheckPixelFormat(image.PixelFormat); int pixelSize = System.Drawing.Image.GetPixelFormatSize(image.PixelFormat) / 8; // image dimension int imageWidth = image.Width; int imageHeight = image.Height; int stride = image.Stride; // check if there is something to draw if ( ((point1.X < 0) && (point2.X < 0)) || ((point1.Y < 0) && (point2.Y < 0)) || ((point1.X >= imageWidth) && (point2.X >= imageWidth)) || ((point1.Y >= imageHeight) && (point2.Y >= imageHeight))) { // nothing to draw return; } CheckEndPoint(imageWidth, imageHeight, point1, ref point2); CheckEndPoint(imageWidth, imageHeight, point2, ref point1); // check again if there is something to draw if ( ((point1.X < 0) && (point2.X < 0)) || ((point1.Y < 0) && (point2.Y < 0)) || ((point1.X >= imageWidth) && (point2.X >= imageWidth)) || ((point1.Y >= imageHeight) && (point2.Y >= imageHeight))) { // nothing to draw return; } int startX = point1.X; int startY = point1.Y; int stopX = point2.X; int stopY = point2.Y; // compute pixel for grayscale image byte gray = 0; if (image.PixelFormat == PixelFormat.Format8bppIndexed) { gray = (byte)(0.2125 * color.R + 0.7154 * color.G + 0.0721 * color.B); } // draw the line int dx = stopX - startX; int dy = stopY - startY; if (Math.Abs(dx) >= Math.Abs(dy)) { // the line is more horizontal, we'll plot along the X axis float slope = (dx != 0) ? (float)dy / dx : 0; int step = (dx > 0) ? 1 : -1; // correct dx so last point is included as well dx += step; if (image.PixelFormat == PixelFormat.Format8bppIndexed) { // grayscale image for (int x = 0; x != dx; x += step) { int px = startX + x; int py = (int)((float)startY + (slope * (float)x)); byte *ptr = (byte *)image.ImageData.ToPointer() + py * stride + px; * ptr = gray; } } else { // color image for (int x = 0; x != dx; x += step) { int px = startX + x; int py = (int)((float)startY + (slope * (float)x)); byte *ptr = (byte *)image.ImageData.ToPointer() + py * stride + px * pixelSize; ptr[RGB.R] = color.R; ptr[RGB.G] = color.G; ptr[RGB.B] = color.B; } } } else { // the line is more vertical, we'll plot along the y axis. float slope = (dy != 0) ? (float)dx / dy : 0; int step = (dy > 0) ? 1 : -1; // correct dy so last point is included as well dy += step; if (image.PixelFormat == PixelFormat.Format8bppIndexed) { // grayscale image for (int y = 0; y != dy; y += step) { int px = (int)((float)startX + (slope * (float)y)); int py = startY + y; byte *ptr = (byte *)image.ImageData.ToPointer() + py * stride + px; * ptr = gray; } } else { // color image for (int y = 0; y != dy; y += step) { int px = (int)((float)startX + (slope * (float)y)); int py = startY + y; byte *ptr = (byte *)image.ImageData.ToPointer() + py * stride + px * pixelSize; ptr[RGB.R] = color.R; ptr[RGB.G] = color.G; ptr[RGB.B] = color.B; } } } }
/// <summary> /// Draw a line on the specified image. /// </summary> /// /// <param name="imageData">Source image data to draw on.</param> /// <param name="point1">The first point to connect.</param> /// <param name="point2">The second point to connect.</param> /// <param name="color">Line's color.</param> /// /// <exception cref="UnsupportedImageFormatException">The source image has incorrect pixel format.</exception> /// public static unsafe void Line(BitmapData imageData, IntPoint point1, IntPoint point2, Color color) { Line(new UnmanagedImage(imageData), point1, point2, color); }