// Create motion zones' image private unsafe void CreateMotionZonesFrame() { lock (sync) { // free previous motion zones frame if (zonesFrame != null) { zonesFrame.Dispose(); zonesFrame = null; } // create motion zones frame only in the case if the algorithm has processed at least one frame if ((motionZones != null) && (motionZones.Length != 0) && (videoWidth != 0)) { zonesFrame = UnmanagedImage.Create(videoWidth, videoHeight, PixelFormat.Format8bppIndexed); Rectangle imageRect = new Rectangle(0, 0, videoWidth, videoHeight); // draw all motion zones on motion frame foreach (Rectangle rect in motionZones) { rect.Intersect(imageRect); // rectangle's dimenstion int rectWidth = rect.Width; int rectHeight = rect.Height; // start pointer int stride = zonesFrame.Stride; byte *ptr = (byte *)zonesFrame.ImageData.ToPointer() + rect.Y * stride + rect.X; for (int y = 0; y < rectHeight; y++) { UnmanagedMemoryHelper.SetUnmanagedMemory(ptr, 255, rectWidth); ptr += stride; } } } } }
/// <summary> /// 为新的图片创建非托管内存 /// </summary> /// <param name="width">Image width.</param> /// <param name="height">Image height.</param> /// <param name="pixelFormat">Image pixel format.</param> /// <returns>Return image allocated in unmanaged memory.</returns> /// <remarks><para>Allocate new image with specified attributes in unmanaged memory.</para> /// <para><note>The method supports only /// <see cref="System.Drawing.Imaging.PixelFormat">Format8bppIndexed</see>, /// <see cref="System.Drawing.Imaging.PixelFormat">Format16bppGrayScale</see>, /// <see cref="System.Drawing.Imaging.PixelFormat">Format24bppRgb</see>, /// <see cref="System.Drawing.Imaging.PixelFormat">Format32bppRgb</see>, /// <see cref="System.Drawing.Imaging.PixelFormat">Format32bppArgb</see>, /// <see cref="System.Drawing.Imaging.PixelFormat">Format32bppPArgb</see>, /// <see cref="System.Drawing.Imaging.PixelFormat">Format48bppRgb</see>, /// <see cref="System.Drawing.Imaging.PixelFormat">Format64bppArgb</see> and /// <see cref="System.Drawing.Imaging.PixelFormat">Format64bppPArgb</see> pixel formats. /// In the case if <see cref="System.Drawing.Imaging.PixelFormat">Format8bppIndexed</see> /// format is specified, pallete is not not created for the image (supposed that it is /// 8 bpp grayscale image). /// </note></para> /// </remarks> /// <exception cref="UnsupportedImageFormatException">Unsupported pixel format was specified.</exception> /// <exception cref="InvalidImagePropertiesException">Invalid image size was specified.</exception> public static UnmanagedImage Create(int width, int height, PixelFormat pixelFormat) { int bytesPerPixel = 0; // calculate bytes per pixel switch (pixelFormat) { case PixelFormat.Format8bppIndexed: bytesPerPixel = 1; break; case PixelFormat.Format16bppGrayScale: bytesPerPixel = 2; break; case PixelFormat.Format24bppRgb: bytesPerPixel = 3; break; case PixelFormat.Format32bppRgb: case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: bytesPerPixel = 4; break; case PixelFormat.Format48bppRgb: bytesPerPixel = 6; break; case PixelFormat.Format64bppArgb: case PixelFormat.Format64bppPArgb: bytesPerPixel = 8; break; default: throw new UnsupportedImageFormatException("Can not create image with specified pixel format."); } // check image size if ((width <= 0) || (height <= 0)) { throw new InvalidImagePropertiesException("Invalid image size specified."); } // calculate stride int stride = width * bytesPerPixel; if (stride % 4 != 0) { stride += (4 - (stride % 4)); } // allocate memory for the image IntPtr imageData = System.Runtime.InteropServices.Marshal.AllocHGlobal(stride * height); UnmanagedMemoryHelper.SetUnmanagedMemory(imageData, 0, stride * height); UnmanagedImage image = new UnmanagedImage(imageData, width, height, stride, pixelFormat); image.mustBeDisposed = true; return(image); }
/// <summary> /// Fill rectangle on the specified image. /// </summary> /// /// <param name="image">Source image to draw on.</param> /// <param name="rectangle">Rectangle's coordinates to fill.</param> /// <param name="color">Rectangle's color.</param> /// /// <exception cref="UnsupportedImageFormatException">The source image has incorrect pixel format.</exception> /// public static unsafe void FillRectangle(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); // do the job byte *ptr = (byte *)image.ImageData.ToPointer() + startY * stride + startX * pixelSize; if (image.PixelFormat == PixelFormat.Format8bppIndexed) { // grayscale image byte gray = (byte)(0.2125 * color.R + 0.7154 * color.G + 0.0721 * color.B); int fillWidth = stopX - startX + 1; for (int y = startY; y <= stopY; y++) { UnmanagedMemoryHelper.SetUnmanagedMemory(ptr, gray, fillWidth); ptr += stride; } } else { // color image byte red = color.R; byte green = color.G; byte blue = color.B; int offset = stride - (stopX - startX + 1) * pixelSize; for (int y = startY; y <= stopY; y++) { for (int x = startX; x <= stopX; x++, ptr += pixelSize) { ptr[RGB.R] = red; ptr[RGB.G] = green; ptr[RGB.B] = blue; } ptr += offset; } } }