How to sharpen a Bitmap?


Answers

This might be helpful to you

public static Bitmap ImageSharpen(Bitmap InpImg)
{
    Bitmap sharpenImage = new Bitmap(InpImg.Width, InpImg.Height);

    int wdth = InpImg.Width;
    int hght = InpImg.Height;

    double[,] filter = new double[3, 3];

    filter[0, 0] = filter[0, 1] = filter[0, 2] = filter[1, 0] = filter[1, 2] = filter[2, 0] = filter[2, 1] = filter[2, 2] = -1;
    filter[1, 1] = 9;

    double factor = 1.0;
    double bias = 0.0;

    Color[,] result = new Color[InpImg.Width, InpImg.Height];

    for (int x = 0; x < wdth; ++x)
    {
        for (int y = 0; y < hght; ++y)
        {
            double red = 0.0, green = 0.0, blue = 0.0;
            Color imageColor = InpImg.GetPixel(x, y);
            for (int filterX = 0; filterX < 3; filterX++)
            {
                for (int filterY = 0; filterY < 3; filterY++)
                {
                    int imageX = (x - 3 / 2 + filterX + wdth) % wdth;
                    int imageY = (y - 3 / 2 + filterY + hght) % hght;
                    Color imageColor = InpImg.GetPixel(imageX, imageY);
                    red += imageColor.R * filter[filterX, filterY];
                    green += imageColor.G * filter[filterX, filterY];
                    blue += imageColor.B * filter[filterX, filterY];
                }
                int r = Math.Min(Math.Max((int)(factor * red + bias), 0), 255);
                int g = Math.Min(Math.Max((int)(factor * green + bias), 0), 255);
                int b = Math.Min(Math.Max((int)(factor * blue + bias), 0), 255);

                result[x, y] = Color.FromArgb(r, g, b);
            }
        }
    }
    for (int i = 0; i < wdth; ++i)
    {
        for (int j = 0; j < hght; ++j)
        {
            sharpenImage.SetPixel(i, j, result[i, j]);
        }
    }
    return sharpenImage;
}
Question

I am now developing an app for Android in Xamarin and I am stuck on a little step. I was searching on the interwebs for a sharpening alogrithm for MonoDroid and everything I find doesn`t seem to work. Can anybody provide me with some as-is script or some documentation? Thanks in advance.




How to add System.Drawing in xamarin?

As @Cheesebaron quoted once if forum :

If you look at http://docs.xamarin.com/guides/android/advanced_topics/assemblies you will see that System.Drawing is not a part of the Assemblies shipped with Xamarin.Android, the same goes for Xamarin.iOS.

You will need to use the Android counterparts to filter images.


The alternative method is to add System.Drawing.dll as references.

Right click on References --> Edit References --> .Net Assembly --> Browse... --> C:\Windows\Microsoft.NET\Framework\v4.0.30319 --> select System.Drawing.dll.

Now try to make use of Bitmap class using System.Drawing;




I took Daniel's answer and modified it for performance, by using BitmapData class, since using GetPixel/SetPixel is very expensive and inappropriate for performance-hungry systems. It works exactly the same as the previous solution and can be used instead.

   public static Bitmap Sharpen(Bitmap image)
    {
        Bitmap sharpenImage = (Bitmap)image.Clone();

        int filterWidth = 3;
        int filterHeight = 3;
        int width = image.Width;
        int height = image.Height;

        // Create sharpening filter.
        double[,] filter = new double[filterWidth, filterHeight];
        filter[0, 0] = filter[0, 1] = filter[0, 2] = filter[1, 0] = filter[1, 2] = filter[2, 0] = filter[2, 1] = filter[2, 2] = -1;
        filter[1, 1] = 9;

        double factor = 1.0;
        double bias = 0.0;

        Color[,] result = new Color[image.Width, image.Height];

        // Lock image bits for read/write.
        BitmapData pbits = sharpenImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        // Declare an array to hold the bytes of the bitmap.
        int bytes = pbits.Stride * height;
        byte[] rgbValues = new byte[bytes];

        // Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(pbits.Scan0, rgbValues, 0, bytes);

        int rgb;
        // Fill the color array with the new sharpened color values.
        for (int x = 0; x < width; ++x)
        {
            for (int y = 0; y < height; ++y)
            {
                double red = 0.0, green = 0.0, blue = 0.0;

                for (int filterX = 0; filterX < filterWidth; filterX++)
                {
                    for (int filterY = 0; filterY < filterHeight; filterY++)
                    {
                        int imageX = (x - filterWidth / 2 + filterX + width) % width;
                        int imageY = (y - filterHeight / 2 + filterY + height) % height;

                        rgb = imageY * pbits.Stride + 3 * imageX;

                        red += rgbValues[rgb + 2] * filter[filterX, filterY];
                        green += rgbValues[rgb + 1] * filter[filterX, filterY];
                        blue += rgbValues[rgb + 0] * filter[filterX, filterY];
                    }
                    int r = Math.Min(Math.Max((int)(factor * red + bias), 0), 255);
                    int g = Math.Min(Math.Max((int)(factor * green + bias), 0), 255);
                    int b = Math.Min(Math.Max((int)(factor * blue + bias), 0), 255);

                    result[x, y] = Color.FromArgb(r, g, b);
                }
            }
        }

        // Update the image with the sharpened pixels.
        for (int x = 0; x < width; ++x)
        {
            for (int y = 0; y < height; ++y)
            {
                rgb = y * pbits.Stride + 3 * x;

                rgbValues[rgb + 2] = result[x, y].R;
                rgbValues[rgb + 1] = result[x, y].G;
                rgbValues[rgb + 0] = result[x, y].B;
            }
        }

        // Copy the RGB values back to the bitmap.
        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, pbits.Scan0, bytes);
        // Release image bits.
        sharpenImage.UnlockBits(pbits);

        return sharpenImage;
    }




Tags