/// <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) { // check pixel format of the source image CheckSourceFormat(imageData.PixelFormat); // get width and height int width = imageData.Width; int height = imageData.Height; // destination image format PixelFormat dstPixelFormat = FormatTranslations[imageData.PixelFormat]; // 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); try { // process the filter ProcessFilter(new UnmanagedImage(imageData), new UnmanagedImage(dstData)); } finally { // unlock destination images dstImage.UnlockBits(dstData); } return(dstImage); }
/// <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."); } }