示例#1
0
        /// <summary>
        /// Clone the unmanaged images.
        /// </summary>
        ///
        /// <returns>Returns clone of the unmanaged image.</returns>
        ///
        /// <remarks><para>The method does complete cloning of the object.</para></remarks>
        ///
        public UnmanagedImage Clone()
        {
            // allocate memory for the image
            IntPtr newImageData = System.Runtime.InteropServices.Marshal.AllocHGlobal(stride * height);

            System.GC.AddMemoryPressure(stride * height);

            UnmanagedImage newImage = new UnmanagedImage(newImageData, width, height, stride, pixelFormat);

            newImage.mustBeDisposed = true;

            SystemTools.CopyUnmanagedMemory(newImageData, imageData, stride * height);

            return(newImage);
        }
示例#2
0
        /// <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>
        /// Apply filter to an image in unmanaged memory.
        /// </summary>
        ///
        /// <param name="sourceImage">Source image in unmanaged memory to apply filter to.</param>
        /// <param name="destinationImage">Destination image in unmanaged memory to put result into.</param>
        ///
        /// <remarks><para>The method keeps the source image unchanged and puts result of image processing
        /// into destination image.</para>
        ///
        /// <para><note>The destination image must have the same width and height as source image. Also
        /// destination image must have pixel format, which is expected by particular filter (see
        /// <see cref="FormatTranslations"/> property for information about pixel format conversions).</note></para>
        /// </remarks>
        ///
        /// <exception cref="UnsupportedImageFormatException">Unsupported pixel format of the source image.</exception>
        /// <exception cref="InvalidImagePropertiesException">Incorrect destination pixel format.</exception>
        /// <exception cref="InvalidImagePropertiesException">Destination image has wrong width and/or height.</exception>
        ///
        public void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
        {
            // check pixel format of the source image
            CheckSourceFormat(sourceImage.PixelFormat);

            // ensure destination image has correct format
            if (destinationImage.PixelFormat != sourceImage.PixelFormat)
            {
                throw new InvalidImagePropertiesException("Destination pixel format must be the same as pixel format of source image.");
            }

            // ensure destination image has correct size
            if ((destinationImage.Width != sourceImage.Width) || (destinationImage.Height != sourceImage.Height))
            {
                throw new InvalidImagePropertiesException("Destination image must have the same width and height as source image.");
            }

            // usually stride will be the same for 2 images of the size size/format,
            // but since this a public a method and users may provide any evil, we to need check it
            int dstStride = destinationImage.Stride;
            int srcStride = sourceImage.Stride;
            int lineSize  = Math.Min(srcStride, dstStride);

            unsafe
            {
                byte *dst = (byte *)destinationImage.ImageData.ToPointer();
                byte *src = (byte *)sourceImage.ImageData.ToPointer();

                // copy image
                for (int y = 0, height = sourceImage.Height; y < height; y++)
                {
                    SystemTools.CopyUnmanagedMemory(dst, src, lineSize);
                    dst += dstStride;
                    src += srcStride;
                }
            }

            // process the filter
            ProcessFilter(destinationImage, new Rectangle(0, 0, destinationImage.Width, destinationImage.Height));
        }
        /// <summary>
        /// Apply filter to an image.
        /// </summary>
        ///
        /// <param name="imageData">Source image to apply filter to.</param>
        ///
        /// <returns>Returns filter's result obtained by applying the filter to
        /// the source image.</returns>
        ///
        /// <remarks>The filter accepts bitmap data as input and returns the result
        /// of image processing filter as new image. The source image data are kept
        /// unchanged.</remarks>
        ///
        /// <exception cref="UnsupportedImageFormatException">Unsupported pixel format of the source image.</exception>
        ///
        public Bitmap Apply(BitmapData imageData)
        {
            // destination image format
            PixelFormat dstPixelFormat = imageData.PixelFormat;

            // check pixel format of the source image
            CheckSourceFormat(dstPixelFormat);

            // get image dimension
            int width  = imageData.Width;
            int height = imageData.Height;

            // create new image of required format
            Bitmap dstImage = (dstPixelFormat == PixelFormat.Format8bppIndexed) ?
                              AForgeImage.CreateGrayscaleImage(width, height) :
                              new Bitmap(width, height, dstPixelFormat);

            // lock destination bitmap data
            BitmapData dstData = dstImage.LockBits(
                new Rectangle(0, 0, width, height),
                ImageLockMode.ReadWrite, dstPixelFormat);

            // copy image
            SystemTools.CopyUnmanagedMemory(dstData.Scan0, imageData.Scan0, imageData.Stride * height);

            try
            {
                // process the filter
                ProcessFilter(new UnmanagedImage(dstData), new Rectangle(0, 0, width, height));
            }
            finally
            {
                // unlock destination images
                dstImage.UnlockBits(dstData);
            }

            return(dstImage);
        }
示例#5
0
        /// <summary>
        /// Create managed image from the unmanaged.
        /// </summary>
        ///
        /// <param name="makeCopy">Make a copy of the unmanaged image or not.</param>
        ///
        /// <returns>Returns managed copy of the unmanaged image.</returns>
        ///
        /// <remarks><para>If the <paramref name="makeCopy"/> is set to <see langword="true"/>, then the method
        /// creates a managed copy of the unmanaged image, so the managed image stays valid even when the unmanaged
        /// image gets disposed. However, setting this parameter to <see langword="false"/> creates a managed image which is
        /// just a wrapper around the unmanaged image. So if unmanaged image is disposed, the
        /// managed image becomes no longer valid and accessing it will generate an exception.</para></remarks>
        ///
        /// <exception cref="InvalidImagePropertiesException">The unmanaged image has some invalid properties, which results
        /// in failure of converting it to managed image. This may happen if user used the
        /// <see cref="UnmanagedImage(IntPtr, int, int, int, PixelFormat)"/> constructor specifying some
        /// invalid parameters.</exception>
        ///
        public Bitmap ToManagedImage(bool makeCopy)
        {
            Bitmap dstImage = null;

            try
            {
                if (!makeCopy)
                {
                    dstImage = new Bitmap(width, height, stride, pixelFormat, imageData);
                    if (pixelFormat == PixelFormat.Format8bppIndexed)
                    {
                        AForgeImage.SetGrayscalePalette(dstImage);
                    }
                }
                else
                {
                    // create new image of required format
                    dstImage = (pixelFormat == PixelFormat.Format8bppIndexed) ?
                               AForgeImage.CreateGrayscaleImage(width, height) :
                               new Bitmap(width, height, pixelFormat);

                    // lock destination bitmap data
                    BitmapData dstData = dstImage.LockBits(
                        new Rectangle(0, 0, width, height),
                        ImageLockMode.ReadWrite, pixelFormat);

                    int dstStride = dstData.Stride;
                    int lineSize  = Math.Min(stride, dstStride);

                    unsafe
                    {
                        byte *dst = (byte *)dstData.Scan0.ToPointer();
                        byte *src = (byte *)imageData.ToPointer();

                        if (stride != dstStride)
                        {
                            // copy image
                            for (int y = 0; y < height; y++)
                            {
                                SystemTools.CopyUnmanagedMemory(dst, src, lineSize);
                                dst += dstStride;
                                src += stride;
                            }
                        }
                        else
                        {
                            SystemTools.CopyUnmanagedMemory(dst, src, stride * height);
                        }
                    }

                    // unlock destination images
                    dstImage.UnlockBits(dstData);
                }

                return(dstImage);
            }
            catch (Exception)
            {
                if (dstImage != null)
                {
                    dstImage.Dispose();
                }

                throw new InvalidImagePropertiesException("The unmanaged image has some invalid properties, which results in failure of converting it to managed image.");
            }
        }
示例#6
0
        /// <summary>
        /// Allocate new image in unmanaged memory.
        /// </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);

            SystemTools.SetUnmanagedMemory(imageData, 0, stride * height);
            System.GC.AddMemoryPressure(stride * height);

            UnmanagedImage image = new UnmanagedImage(imageData, width, height, stride, pixelFormat);

            image.mustBeDisposed = true;

            return(image);
        }