/// <summary> /// Clone image. /// </summary> /// /// <param name="sourceData">Source image data.</param> /// /// <returns>Clones image from source image data. The message does not clone pallete in the /// case if the source image has indexed pixel format.</returns> /// public static Bitmap Clone(BitmapData sourceData) { // get source image size int width = sourceData.Width; int height = sourceData.Height; // create new image Bitmap destination = new Bitmap(width, height, sourceData.PixelFormat); // lock destination bitmap data BitmapData destinationData = destination.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, destination.PixelFormat); SystemTools.CopyUnmanagedMemory(destinationData.Scan0, sourceData.Scan0, height * sourceData.Stride); // unlock destination image destination.UnlockBits(destinationData); return(destination); }
/// <summary> /// Draw rectangle on the specified image. /// </summary> /// /// <param name="image">Source image to draw on.</param> /// <param name="rectangle">Rectangle's coordinates to draw.</param> /// <param name="color">Rectangle's color.</param> /// /// <exception cref="UnsupportedImageFormatException">The source image has incorrect pixel format.</exception> /// public static unsafe void Rectangle(UnmanagedImage image, Rectangle rectangle, Color color) { 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; // rectangle dimension and position int rectX1 = rectangle.X; int rectY1 = rectangle.Y; int rectX2 = rectangle.X + rectangle.Width - 1; int rectY2 = rectangle.Y + rectangle.Height - 1; // check if rectangle is in the image if ((rectX1 >= imageWidth) || (rectY1 >= imageHeight) || (rectX2 < 0) || (rectY2 < 0)) { // nothing to draw return; } int startX = Math.Max(0, rectX1); int stopX = Math.Min(imageWidth - 1, rectX2); int startY = Math.Max(0, rectY1); int stopY = Math.Min(imageHeight - 1, rectY2); if (image.PixelFormat == PixelFormat.Format8bppIndexed) { // grayscale image byte gray = (byte)(0.2125 * color.R + 0.7154 * color.G + 0.0721 * color.B); // draw top horizontal line if (rectY1 >= 0) { byte *ptr = (byte *)image.ImageData.ToPointer() + rectY1 * stride + startX; SystemTools.SetUnmanagedMemory(ptr, gray, stopX - startX); } // draw bottom horizontal line if (rectY2 < imageHeight) { byte *ptr = (byte *)image.ImageData.ToPointer() + rectY2 * stride + startX; SystemTools.SetUnmanagedMemory(ptr, gray, stopX - startX); } // draw left vertical line if (rectX1 >= 0) { byte *ptr = (byte *)image.ImageData.ToPointer() + startY * stride + rectX1; for (int y = startY; y <= stopY; y++, ptr += stride) { *ptr = gray; } } // draw right vertical line if (rectX2 < imageWidth) { byte *ptr = (byte *)image.ImageData.ToPointer() + startY * stride + rectX2; for (int y = startY; y <= stopY; y++, ptr += stride) { *ptr = gray; } } } else { // color image byte red = color.R; byte green = color.G; byte blue = color.B; // draw top horizontal line if (rectY1 >= 0) { byte *ptr = (byte *)image.ImageData.ToPointer() + rectY1 * stride + startX * pixelSize; for (int x = startX; x <= stopX; x++, ptr += pixelSize) { ptr[RGB.R] = red; ptr[RGB.G] = green; ptr[RGB.B] = blue; } } // draw bottom horizontal line if (rectY2 < imageHeight) { byte *ptr = (byte *)image.ImageData.ToPointer() + rectY2 * stride + startX * pixelSize; for (int x = startX; x <= stopX; x++, ptr += pixelSize) { ptr[RGB.R] = red; ptr[RGB.G] = green; ptr[RGB.B] = blue; } } // draw left vertical line if (rectX1 >= 0) { byte *ptr = (byte *)image.ImageData.ToPointer() + startY * stride + rectX1 * pixelSize; for (int y = startY; y <= stopY; y++, ptr += stride) { ptr[RGB.R] = red; ptr[RGB.G] = green; ptr[RGB.B] = blue; } } // draw right vertical line if (rectX2 < imageWidth) { byte *ptr = (byte *)image.ImageData.ToPointer() + startY * stride + rectX2 * pixelSize; for (int y = startY; y <= stopY; y++, ptr += stride) { ptr[RGB.R] = red; ptr[RGB.G] = green; ptr[RGB.B] = blue; } } } }