Example #1
0
        // 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);
        }
Example #3
0
        /// <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;
                }
            }
        }