LitDev.Engines.FIP.OilPaint C# (CSharp) Method

OilPaint() public method

Oil paint filtration
public OilPaint ( Bitmap OriginalImage, int R, int Level ) : Bitmap
OriginalImage System.Drawing.Bitmap original ARGB image
R int Radius of oil paint algorithm
Level int Available levels of intensity
return System.Drawing.Bitmap
        public Bitmap OilPaint(Bitmap OriginalImage, int R, int Level)
        {
            Bitmap image = OriginalImage;
            FastPixel fpImage = new FastPixel(image);
            Bitmap image2 = new Bitmap(fpImage.Width, fpImage.Height);
            FastPixel fpImage2 = new FastPixel(image2);

            if (Level < 1 || Level > 255)
            {
                throw new Exception("Available intensity levels must be between 1 and 255");
            }

            if (R % 2 == 0)
            {
                throw new Exception("Filter mask dimension must be odd.");
            }

            if (R < 3)
            {
                throw new Exception("Filter mask dimension must be greater or equal 3.");
            }

            int range = (int)Math.Floor(Convert.ToDouble(R / 2));

            for (int m = range; m < fpImage.Width - range; m++)
            {
                for (int n = range; n < fpImage.Height - range; n++)
                {

                    Double[,,] roi = new Double[3, R, R];

                    int tmpi = 0;
                    int tmpj = 0;

                    int newValueR = 0;
                    int newValueG = 0;
                    int newValueB = 0;

                    for (int i = m - range; i < m + range + 1; i++)
                    {
                        for (int j = n - range; j < n + range + 1; j++)
                        {
                            Color pixel = fpImage.GetPixel(i, j);
                            Double pR = Convert.ToDouble(pixel.R);
                            Double pG = Convert.ToDouble(pixel.G);
                            Double pB = Convert.ToDouble(pixel.B);

                            roi[0, tmpi, tmpj] = (int)pR;
                            roi[1, tmpi, tmpj] = (int)pG;
                            roi[2, tmpi, tmpj] = (int)pB;

                            tmpj++;
                        }

                        tmpi++;
                        tmpj = 0;
                    }

                    int[] avgR = new int[256];
                    int[] avgG = new int[256];
                    int[] avgB = new int[256];
                    int[] intCnt = new int[256];

                    for (int k = 0; k < R; k++)
                    {
                        for (int l = 0; l < R; l++)
                        {
                            int intensity = (int)(((roi[0, k, l] + roi[1, k, l] + roi[2, k, l]) / 3) * Convert.ToDouble(Level) / 255);
                            intCnt[intensity]++;
                            avgR[intensity] += (int)roi[0, k, l];
                            avgG[intensity] += (int)roi[1, k, l];
                            avgB[intensity] += (int)roi[2, k, l];

                        }
                    }

                    int maxCur = 0;
                    int maxIndex = 0;

                    for (int a = 0; a < 256; a++)
                    {
                        if (intCnt[a] > maxCur)
                        {
                            maxCur = intCnt[a];
                            maxIndex = a;
                        }
                    }

                    newValueR = avgR[maxIndex] / maxCur;
                    newValueG = avgG[maxIndex] / maxCur;
                    newValueB = avgB[maxIndex] / maxCur;

                    if (newValueR > 255) newValueR = 255;
                    if (newValueR < 0) newValueR = 0;

                    if (newValueG > 255) newValueG = 255;
                    if (newValueG < 0) newValueG = 0;

                    if (newValueB > 255) newValueB = 255;
                    if (newValueB < 0) newValueB = 0;

                    fpImage2.SetPixel(m, n, Color.FromArgb(255, newValueR, newValueG, newValueB));

                }
            }

            fpImage.Unlock(false);
            fpImage2.Unlock(true);
            return image2;
        }