/// <summary> /// Resizes an image by the specified scale factors using the specified sampling mode. /// </summary> /// <param name="image">Image to resize.</param> /// <param name="scaleX">Scale factor to apply in X direction.</param> /// <param name="scaleY">Scale factor to apply in Y direction.</param> /// <param name="mode">Sampling mode for sampling of pixels.</param> /// <returns>Returns a new image scaled by the specified scale factors.</returns> public static Shared <Image> Scale(this Image image, float scaleX, float scaleY, SamplingMode mode) { if (scaleX == 0.0 || scaleY == 0.0) { throw new System.Exception("Unexpected scale factors"); } if (image.PixelFormat == PixelFormat.Gray_16bpp) { throw new System.NotSupportedException( "Scaling 16bpp images is not currently supported. " + "Convert to a supported format such as color or 8bpp grayscale first."); } int dstWidth = (int)(image.Width * scaleX); int dstHeight = (int)(image.Height * scaleY); using (var bitmap = new Bitmap(dstWidth, dstHeight)) { using (var graphics = Graphics.FromImage(bitmap)) { graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; switch (mode) { case SamplingMode.Point: graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighSpeed; break; case SamplingMode.Bilinear: graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; break; case SamplingMode.Bicubic: graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; break; } graphics.ScaleTransform(scaleX, scaleY); using (var managedimg = image.ToManagedImage()) { graphics.DrawImage(managedimg, new Point(0, 0)); } return(ImagePool.GetOrCreate(bitmap)); } } }
/// <summary> /// Draws a circle centered at the specified pixel (p0) with the specified radius /// </summary> /// <param name="image">Image to draw on</param> /// <param name="p0">Pixel coordinates for center of circle</param> /// <param name="radius">Radius of the circle</param> /// <param name="color">Color to use for drawing</param> /// <param name="width">Width of line</param> public static void DrawCircle(this Image image, Point p0, int radius, Color color, int width) { Bitmap bm = image.ToManagedImage(false); var graphics = Graphics.FromImage(bm); var pen = new Pen(new SolidBrush(color)); pen.Width = width; graphics.DrawEllipse(pen, p0.X - radius, p0.Y - radius, 2 * radius, 2 * radius); }
/// <summary> /// Draws a line from point p0 to p1 in pixel coordinates on the image /// </summary> /// <param name="image">Image to draw on</param> /// <param name="p0">Pixel coordinates for start of line</param> /// <param name="p1">Pixel coordinates for end of line</param> /// <param name="color">Color to use for drawing</param> /// <param name="width">Width of line</param> public static void DrawLine(this Image image, Point p0, Point p1, Color color, int width) { Bitmap bm = image.ToManagedImage(false); var graphics = Graphics.FromImage(bm); var pen = new Pen(new SolidBrush(color)); pen.Width = width; graphics.DrawLine(pen, p0, p1); }
/// <summary> /// Draws a rectangle at the specified pixel coordinates on the image /// </summary> /// <param name="image">Image to draw on</param> /// <param name="rect">Pixel coordinates for rectangle</param> /// <param name="color">Color to use for drawing</param> /// <param name="width">Width of line</param> public static void DrawRectangle(this Image image, Rectangle rect, Color color, int width) { Bitmap bm = image.ToManagedImage(false); var graphics = Graphics.FromImage(bm); var pen = new Pen(new SolidBrush(color)); pen.Width = width; graphics.DrawRectangle(pen, rect); }
/// <summary> /// Resizes an image by the specified scale factors using the specified sampling mode /// </summary> /// <param name="image">Image to resize</param> /// <param name="xScale">Scale factor to apply in X direction</param> /// <param name="yScale">Scale factor to apply in Y direction</param> /// <param name="mode">Sampling mode for sampling of pixels</param> /// <returns>Returns a new image scaled by the specified scale factors</returns> public static Shared <Image> Scale(this Image image, float xScale, float yScale, SamplingMode mode) { if (xScale == 0.0 || yScale == 0.0) { throw new System.Exception("Unexpected scale factors"); } int dstWidth = (int)(image.Width * xScale); int dstHeight = (int)(image.Height * yScale); var bitmap = new Bitmap(dstWidth, dstHeight); var graphics = Graphics.FromImage(bitmap); graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; switch (mode) { case SamplingMode.Point: graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighSpeed; break; case SamplingMode.Bilinear: graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; break; case SamplingMode.Bicubic: graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; break; } graphics.ScaleTransform(xScale, yScale); graphics.DrawImage(image.ToManagedImage(), new Point(0, 0)); return(ImagePool.GetOrCreate(bitmap)); }
/// <summary> /// Flips an image along a specified axis /// </summary> /// <param name="image">Image to flip</param> /// <param name="mode">Axis along which to flip</param> /// <returns>A new flipped image</returns> public static Shared <Image> Flip(this Image image, FlipMode mode) { var bitmap = new Bitmap(image.Width, image.Height); var graphics = Graphics.FromImage(bitmap); switch (mode) { case FlipMode.AlongHorizontalAxis: graphics.TranslateTransform(0.0f, image.Height - 1); graphics.ScaleTransform(1.0f, -1.0f); break; case FlipMode.AlongVerticalAxis: graphics.TranslateTransform(image.Width - 1, 0.0f); graphics.ScaleTransform(-1.0f, 1.0f); break; } graphics.DrawImage(image.ToManagedImage(), new Point(0, 0)); return(ImagePool.GetOrCreate(bitmap)); }
/// <summary> /// Rotates an image /// </summary> /// <param name="image">Image to rotate</param> /// <param name="angleInDegrees">Number of degrees to rotate in counter clockwise direction</param> /// <param name="mode">Pixel resampling method</param> /// <returns>Rotated image</returns> public static Shared <Image> Rotate(this Image image, float angleInDegrees, SamplingMode mode) { float ca = (float)System.Math.Cos(angleInDegrees * System.Math.PI / 180.0f); float sa = (float)System.Math.Sin(angleInDegrees * System.Math.PI / 180.0f); float minx = 0.0f; float miny = 0.0f; float maxx = 0.0f; float maxy = 0.0f; float x = image.Width - 1; float y = 0.0f; float nx = (x * ca) - (y * sa); float ny = (x * sa) + (y * ca); if (nx < minx) { minx = nx; } if (nx > maxx) { maxx = nx; } if (ny < miny) { miny = ny; } if (ny > maxy) { maxy = ny; } x = image.Width - 1; y = image.Height - 1; nx = (x * ca) - (y * sa); ny = (x * sa) + (y * ca); if (nx < minx) { minx = nx; } if (nx > maxx) { maxx = nx; } if (ny < miny) { miny = ny; } if (ny > maxy) { maxy = ny; } x = 0.0f; y = image.Height - 1; nx = (x * ca) - (y * sa); ny = (x * sa) + (y * ca); if (nx < minx) { minx = nx; } if (nx > maxx) { maxx = nx; } if (ny < miny) { miny = ny; } if (ny > maxy) { maxy = ny; } int dstWidth = (int)(maxx - minx + 1); int dstHeight = (int)(maxy - miny + 1); var bitmap = new Bitmap(dstWidth, dstHeight); var graphics = Graphics.FromImage(bitmap); graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; switch (mode) { case SamplingMode.Point: graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighSpeed; break; case SamplingMode.Bilinear: graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; break; case SamplingMode.Bicubic: graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; break; } graphics.TranslateTransform(-minx, -miny); graphics.RotateTransform(angleInDegrees); graphics.DrawImage(image.ToManagedImage(), new Point(0, 0)); return(ImagePool.GetOrCreate(bitmap)); }
/// <summary> /// Flips an image along a specified axis /// </summary> /// <param name="image">Image to flip</param> /// <param name="mode">Axis along which to flip</param> /// <returns>A new flipped image</returns> public static Shared <Image> Flip(this Image image, FlipMode mode) { if (image.PixelFormat == PixelFormat.Gray_16bpp) { // We can't handle this through GDI. Shared <Image> dstImage = ImagePool.GetOrCreate(image.Width, image.Height, image.PixelFormat); unsafe { int srcBytesPerPixel = PixelFormatHelper.GetBytesPerPixel(image.PixelFormat); int dstBytesPerPixel = PixelFormatHelper.GetBytesPerPixel(dstImage.Resource.PixelFormat); byte *srcRow = (byte *)image.ImageData.ToPointer(); byte *dstRow = (byte *)dstImage.Resource.ImageData.ToPointer(); int ystep = dstImage.Resource.Stride; if (mode == FlipMode.AlongHorizontalAxis) { dstRow += dstImage.Resource.Stride * (image.Height - 1); ystep = -dstImage.Resource.Stride; } int xstep = dstBytesPerPixel; int xoffset = 0; if (mode == FlipMode.AlongVerticalAxis) { xoffset = dstBytesPerPixel * (dstImage.Resource.Width - 1); xstep = -dstBytesPerPixel; } for (int i = 0; i < image.Height; i++) { byte *srcCol = srcRow; byte *dstCol = dstRow + xoffset; for (int j = 0; j < image.Width; j++) { ((ushort *)dstCol)[0] = ((ushort *)srcCol)[0]; srcCol += srcBytesPerPixel; dstCol += xstep; } srcRow += image.Stride; dstRow += ystep; } } return(dstImage); } else { var bitmap = new Bitmap(image.Width, image.Height); var graphics = Graphics.FromImage(bitmap); switch (mode) { case FlipMode.AlongHorizontalAxis: graphics.TranslateTransform(0.0f, image.Height - 1); graphics.ScaleTransform(1.0f, -1.0f); break; case FlipMode.AlongVerticalAxis: graphics.TranslateTransform(image.Width - 1, 0.0f); graphics.ScaleTransform(-1.0f, 1.0f); break; } graphics.DrawImage(image.ToManagedImage(), new Point(0, 0)); return(ImagePool.GetOrCreate(bitmap)); } }