Пример #1
0
        /// <summary>
        /// Create unmanaged image from the specified managed image.
        /// </summary>
        ///
        /// <param name="imageData">Source locked image data.</param>
        ///
        /// <returns>Returns new unmanaged image, which is a copy of source managed image.</returns>
        ///
        /// <remarks><para>The method creates an exact copy of specified managed image, but allocated
        /// in unmanaged memory. This means that managed image may be unlocked right after call to this
        /// method.</para></remarks>
        ///
        /// <exception cref="UnsupportedImageFormatException">Unsupported pixel format of source image.</exception>
        ///
        public static UnmanagedImage FromManagedImage(BitmapData imageData)
        {
            PixelFormat pixelFormat = imageData.PixelFormat;

            // check source pixel format
            if (
                (pixelFormat != PixelFormat.Format8bppIndexed) &&
                (pixelFormat != PixelFormat.Format16bppGrayScale) &&
                (pixelFormat != PixelFormat.Format24bppRgb) &&
                (pixelFormat != PixelFormat.Format32bppRgb) &&
                (pixelFormat != PixelFormat.Format32bppArgb) &&
                (pixelFormat != PixelFormat.Format32bppPArgb) &&
                (pixelFormat != PixelFormat.Format48bppRgb) &&
                (pixelFormat != PixelFormat.Format64bppArgb) &&
                (pixelFormat != PixelFormat.Format64bppPArgb))
            {
                throw new Exception("Unsupported pixel format of the source image.");
            }

            // allocate memory for the image
            IntPtr dstImageData = System.Runtime.InteropServices.Marshal.AllocHGlobal(imageData.Stride * imageData.Height);

            System.GC.AddMemoryPressure(imageData.Stride * imageData.Height);

            UnmanagedImage image = new UnmanagedImage(dstImageData, imageData.Width, imageData.Height, imageData.Stride, pixelFormat);

            SystemTools.CopyUnmanagedMemory(dstImageData, imageData.Scan0, imageData.Stride * imageData.Height);
            image.mustBeDisposed = true;

            return(image);
        }
Пример #2
0
        /// <summary>
        /// Copy unmanaged image.
        /// </summary>
        ///
        /// <param name="destImage">Destination image to copy this image to.</param>
        ///
        /// <remarks><para>The method copies current unmanaged image to the specified image.
        /// Size and pixel format of the destination image must be exactly the same.</para></remarks>
        ///
        /// <exception cref="InvalidImagePropertiesException">Destination image has different size or pixel format.</exception>
        ///
        public void Copy(UnmanagedImage destImage)
        {
            if (
                (width != destImage.width) || (height != destImage.height) ||
                (pixelFormat != destImage.pixelFormat))
            {
                throw new Exception("Destination image has different size or pixel format.");
            }

            if (stride == destImage.stride)
            {
                // copy entire image
                SystemTools.CopyUnmanagedMemory(destImage.imageData, imageData, stride * height);
            }
            else
            {
                unsafe
                {
                    int dstStride  = destImage.stride;
                    int copyLength = (stride < dstStride) ? stride : dstStride;

                    byte *src = (byte *)imageData.ToPointer();
                    byte *dst = (byte *)destImage.imageData.ToPointer();

                    // copy line by line
                    for (int i = 0; i < height; i++)
                    {
                        SystemTools.CopyUnmanagedMemory(dst, src, copyLength);

                        dst += dstStride;
                        src += stride;
                    }
                }
            }
        }
Пример #3
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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        /// <summary>
        /// Process the filter on the specified image.
        /// </summary>
        ///
        /// <param name="sourceData">Source image data.</param>
        /// <param name="destinationData">Destination image data.</param>
        ///
        protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
        {
            // validate rectangle
            Rectangle srcRect = rect;

            srcRect.Intersect(new Rectangle(0, 0, sourceData.Width, sourceData.Height));

            int xmin      = srcRect.Left;
            int ymin      = srcRect.Top;
            int ymax      = srcRect.Bottom - 1;
            int copyWidth = srcRect.Width;

            int srcStride = sourceData.Stride;
            int dstStride = destinationData.Stride;
            int pixelSize = Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
            int copySize  = copyWidth * pixelSize;

            // do the job
            byte *src = (byte *)sourceData.ImageData.ToPointer() + ymin * srcStride + xmin * pixelSize;
            byte *dst = (byte *)destinationData.ImageData.ToPointer();

            if (rect.Top < 0)
            {
                dst -= dstStride * rect.Top;
            }
            if (rect.Left < 0)
            {
                dst -= pixelSize * rect.Left;
            }

            // for each line
            for (int y = ymin; y <= ymax; y++)
            {
                SystemTools.CopyUnmanagedMemory(dst, src, copySize);
                src += srcStride;
                dst += dstStride;
            }
        }
Пример #6
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)
                    {
                        ImageHelper.SetGrayscalePalette(dstImage);
                    }
                }
                else
                {
                    // create new image of required format
                    dstImage = (pixelFormat == PixelFormat.Format8bppIndexed) ?
                               ImageHelper.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 Exception("The unmanaged image has some invalid properties, which results in failure of converting it to managed image.");
            }
        }