Programming

Miscellaneous Code

Code Sample 1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Collections.Concurrent;

namespace Code_Sample1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }






        //Polygon Fill---------------------------------------------------------------------------------------
        public struct Coord
        {
            public double x;
            public double y;
        }
        public struct Box
        {
            public Coord Max;
            public Coord Min;
        }
        public void PolyFill(ref Bitmap bmp, Coord[] Poly, Color FColor)
        {
            Coord P1;
            Coord P2;
            Box Bx;
            double x1 = 0;
            double x2 = 0;
            double xi = 0;
            double yi = 0;
            double[] Table = null; 
            int tb = 0;

            int nvert = Poly.Length - 1;

            if (Poly[nvert].x != Poly[0].x || Poly[nvert].y != Poly[0].y)
            {
                MessageBox.Show("polygon opened , can't fill ");
                return;
            }

            Bx.Max.x = double.MinValue;
            Bx.Max.y = double.MinValue;
            Bx.Min.x = double.MaxValue;
            Bx.Min.y = double.MaxValue;


            for (int i = 0; i <= nvert; i++)
            {
                Bx.Max.x = Math.Max(Bx.Max.x, Poly[i].x);
                Bx.Max.y = Math.Max(Bx.Max.y, Poly[i].y);
                Bx.Min.x = Math.Min(Bx.Min.x, Poly[i].x);
                Bx.Min.y = Math.Min(Bx.Min.y, Poly[i].y);
            }
            // Generic Fill Algorithm
            // x1,x2, Horizontal Scanline Area
            x1 = Bx.Min.x;
            x2 = Bx.Max.x;
            // Scanline y
            double tempVar = Bx.Max.y + 0.0001;
            for (double y = Bx.Min.y + 0.0001; y <= tempVar; y++)
            {
                Table = new double[0];
                tb = 0;
                for (int i = 0; i < nvert; i++) { P1 = Poly[i]; P2 = Poly[i + 1]; if (SEGMENT_INTERSECT(P1.x, P1.y, P2.x, P2.y, x1, y, x2, y) == true) { if (LINE_INTERSECTION(P1.x, P1.y, P2.x, P2.y, x1, y, x2, y, ref xi, ref yi) == false) { tb = tb + 1; //Array.Resize(ref Table, tb + 1); //Table[tb] = xi; AddToLastInArray(ref Table, xi); } } } if (tb > 0) // There is at least an intersection
                {
                    // Ordering the intersections from left to right using a generic QuickSort routine
                    DsortPoly(ref Table);
                    // Filling
                    for (int i = 0; i < tb - 1; i += 2)
                    {
                        Graphics g = Graphics.FromImage(bmp);
                        Pen pp = new Pen(FColor, 1);
                        g.DrawLine(pp, (int)Table[i], (int)y, (int)Table[i + 1], (int)y);
                        g.Dispose();
                    }
                }
            }
            Table = null;
            tb = 0;
        }
        private void DsortPoly(ref double[] objs)
        {
            int num1 = 0;
            int num2 = 0;
            int length = objs.Length - 1;
            double temp;
            for (num1 = 0; num1 <= length + 1; num1++)
            {
                for (num2 = (num1 + 1); num2 <= length; num2++)
                {
                    if (objs[num1] < objs[num2])
                    {
                        temp = objs[num1];
                        objs[num1] = objs[num2];
                        objs[num2] = temp;
                    }
                }
            }
        }
        public Boolean SEGMENT_INTERSECT(double x1, double y1, double X2, double Y2, double x3, double y3, double x4, double y4)
        {
            // Returns True if the segment (x 1,y1)-(x 2,y2) intersects the
            // segment (x3,y3)-(x4,y4)
            Boolean i12 = false;
            bool i21 = false;
            // C he ck Inte rse ction be twe e n (x 3,x 4) - (x 1,x 2)
            if (x1 == X2)
            {
                i12 = (((x3 <= x1) && (x4 >= x1)) || ((x3 >= x1) && (x4 <= x1)));
            }
            else if ((int)y1 == (int)Y2)
            {
                i12 = (((y3 <= y1) && (y4 >= y1)) || ((y3 >= y1) && (y4 <= y1))); } else { i12 = ((((x3 - x1) * (Y2 - y1) >= (y3 - y1) * (X2 - x1)) && ((x4 - x1) * (Y2 - y1) <= (y4 - y1) * (X2 - x1))) || (((x3 - x1) * (Y2 - y1) <= (y3 - y1) * (X2 - x1)) && ((x4 - x1) * (Y2 - y1) >= (y4 - y1) * (X2 - x1))));
            }
            // Check Intersection between (x1,x2)-(x3,x4)
            if ((int)x3 == (int)x4)
            {
                i21 = ((x1 <= x3) && (X2 >= x3)) || ((x1 >= x3) && (X2 <= x3));
            }
            else if ((int)y3 == (int)y4)
            {
                i21 = ((y1 <= y3) && (Y2 >= y3)) || ((y1 >= y3) && (Y2 <= y3)); } else { i21 = ((((x1 - x3) * (y4 - y3) >= (y1 - y3) * (x4 - x3)) && ((X2 - x3) * (y4 - y3) <= (Y2 - y3) * (x4 - x3))) || (((x1 - x3) * (y4 - y3) <= (y1 - y3) * (x4 - x3)) && ((X2 - x3) * (y4 - y3) >= (Y2 - y3) * (x4 - x3))));
            }
            return i12 && i21;
        }
        public Boolean LINE_INTERSECTION(double x1, double y1, double X2, double Y2, double x3, double y3, double x4, double y4, ref double xi, ref double yi)
        {
            double M = 0;
            double n = 0;
            double P = 0;
            double q = 0;
            Boolean Parallelss = false;
            if ((int)x1 == (int)X2)
            {
                if ((int)x3 == (int)x4)
                {
                    Parallelss = true;
                }
                else
                {
                    xi = x1;
                    yi = (y4 - y3) * (xi - x3) / (x4 - x3) + y3;
                }
            }
            else if ((int)x3 == (int)x4)
            {
                xi = x3;
                yi = (Y2 - y1) * (xi - x1) / (X2 - x1) + y1;
            }
            else
            {
                M = (Y2 - y1) / (X2 - x1);
                P = y1 - x1 * M;
                n = (y4 - y3) / (x4 - x3);
                q = y3 - x3 * n;
                if (M == n)
                {
                    Parallelss = true;
                }
                else
                {
                    xi = (q - P) / (M - n);
                    yi = xi * M + P;
                }
            }
            return Parallelss;
        }
        private void AddToLastInArray(ref T[] myarray, T valuetoadd)
        {
            T[] tmp = new T[myarray.Length];
            Array.Copy(myarray, tmp, myarray.Length);
            myarray = new T[tmp.Length + 1];
            Array.Copy(tmp, myarray, tmp.Length);
            myarray[tmp.Length] = valuetoadd;
            tmp = null;
        }
        private void AddToFirstInArray(ref T[] myarray, T valuetoadd)
        {
            T[] tmp = new T[myarray.Length];
            Array.Copy(myarray, tmp, myarray.Length);
            myarray = new T[tmp.Length + 1];
            Array.Copy(tmp, 0, myarray, 1, tmp.Length);
            myarray[0] = valuetoadd;
            tmp = null;
        }


        //uses of polygon fill
        private void button1_Click(object sender, EventArgs e)
        {
            Coord[] Poly = new Coord[5];


            Poly[0].x = 10;
            Poly[0].y = 10;
            Poly[1].x = 100;
            Poly[1].y = 10;
            Poly[2].x = 10;
            Poly[2].y = 200;
            Poly[3].x = 100;
            Poly[3].y = 200;
            Poly[4].x = 10;
            Poly[4].y = 10;



            Bitmap bmp = new Bitmap(400, 400);

            PolyFill(ref bmp, Poly, Color.Blue);

            pictureBox1.Image = bmp;
        }


















        //Quick draw line mathematically--------------------------------------------------------
        private void button2_Click(object sender, EventArgs e)
        {
            int x1 = 10;
            int y1 = 10;
            int x2 = 200;
            int y2 = 100;
            Bitmap bmp = new Bitmap(400, 400);

            int g = (int)Math.Pow(Math.Pow((double)(x2 - x1), 2) + Math.Pow((double)(y2 - y1), 2), 0.5);
            if (g == 0) g = 1;
            for (int r = 0; r <= g; r++) { int i = (int)((double)r * ((double)(x2 - x1) / (double)g) + (double)x1); int j = (int)((double)r * ((double)(y2 - y1) / (double)g) + (double)y1); if ((i >= 0) && (i < bmp.Width) && (j >= 0) && (j < bmp.Height)) bmp.SetPixel(i, j, Color.Red);
            }
            pictureBox1.Image = bmp;
        }


















        //Erode, Dilate bitmap-----------------------------------------------------------------------------

        //Erode darkcolors in bitmap with radius
        private void Erode(ref Bitmap bmp, int radius)
        {

            BitmapData newData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            byte[] g_PixBytes = null;
            byte[] g_OutBytes = null;
            int g_RowSizeBytes = 0;

            g_RowSizeBytes = newData.Stride;

            int total_size = newData.Stride * newData.Height;
            g_PixBytes = new byte[total_size + 1];
            g_OutBytes = new byte[total_size + 1];

            Marshal.Copy(newData.Scan0, g_PixBytes, 0, total_size);
            Array.Copy(g_PixBytes, g_OutBytes, total_size);

            int r = radius;
            Point[] kernel1 = new Point[(r + 1) * 2 * (r + 1) * 2 + 1];
            int kernelcount = 0;
            for (double iy = -r; iy <= r; iy++)
            {
                for (double ix = -r; ix <= r; ix++) { kernel1[kernelcount].X = (int)ix; kernel1[kernelcount].Y = (int)iy; kernelcount = kernelcount + 1; } } int width = bmp.Width; int height = bmp.Height; Parallel.ForEach(Partitioner.Create((int)r, (int)(width - r)), (H) =>
            {
                for (int x = H.Item1; (x < H.Item2); x++)
                {
                    for (int y = r; y < height - r; y++)
                    {
                        int pix = 0;
                        double rmax = double.MinValue;
                        double gmax = double.MinValue;
                        double bmax = double.MinValue;
                        double rmaxind = 0;
                        double gmaxind = 0;
                        double bmaxind = 0;

                        for (int a = 0; a < kernelcount; a++)
                        {
                            pix = (y + (int)kernel1[a].Y) * newData.Stride + 3 * (x + (int)kernel1[a].X);


                            if (rmax < g_PixBytes[pix + 2])
                            {
                                rmax = g_PixBytes[pix + 2];
                                rmaxind = rmax;
                            }
                            if (gmax < g_PixBytes[pix + 1])
                            {
                                gmax = g_PixBytes[pix + 1];
                                gmaxind = gmax;
                            }
                            if (bmax < g_PixBytes[pix + 0])
                            {
                                bmax = g_PixBytes[pix + 0];
                                bmaxind = bmax;
                            }
                        }

                        pix = y * newData.Stride + 3 * x;

                        g_OutBytes[pix + 2] = (byte)rmaxind;
                        g_OutBytes[pix + 1] = (byte)gmaxind;
                        g_OutBytes[pix + 0] = (byte)bmaxind;
                    }
                }
            });

            Marshal.Copy(g_OutBytes, 0, newData.Scan0, total_size);
            bmp.UnlockBits(newData);
            kernel1 = null;
            g_PixBytes = null;
            g_OutBytes = null;

        }
        //Dilate darkcolors in bitmap with radius
        private void Dilate(ref Bitmap bmp, int radius)
        {

            BitmapData newData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            byte[] g_PixBytes = null;
            byte[] g_OutBytes = null;
            int g_RowSizeBytes = 0;

            g_RowSizeBytes = newData.Stride;

            int total_size = newData.Stride * newData.Height;
            g_PixBytes = new byte[total_size + 1];
            g_OutBytes = new byte[total_size + 1];

            Marshal.Copy(newData.Scan0, g_PixBytes, 0, total_size);
            Array.Copy(g_PixBytes, g_OutBytes, total_size);

            int r = radius;
            Point[] kernel1 = new Point[(r + 1) * 2 * (r + 1) * 2 + 1];
            int kernelcount = 0;
            for (double iy = -r; iy <= r; iy++)
            {
                for (double ix = -r; ix <= r; ix++) { kernel1[kernelcount].X = (int)ix; kernel1[kernelcount].Y = (int)iy; kernelcount = kernelcount + 1; } } int width = bmp.Width; int height = bmp.Height; Parallel.ForEach(Partitioner.Create((int)r, (int)(width - r)), (H) =>
            {
                for (int x = H.Item1; (x < H.Item2); x++)
                {
                    for (int y = r; y < height - r; y++)
                    {
                        int pix = 0;
                        double rmax = double.MaxValue;
                        double gmax = double.MaxValue;
                        double bmax = double.MaxValue;
                        double rmaxind = 0;
                        double gmaxind = 0;
                        double bmaxind = 0;

                        for (int a = 0; a < kernelcount; a++) { pix = (y + (int)kernel1[a].Y) * newData.Stride + 3 * (x + (int)kernel1[a].X); if (rmax > g_PixBytes[pix + 2])
                            {
                                rmax = g_PixBytes[pix + 2];
                                rmaxind = rmax;
                            }
                            if (gmax > g_PixBytes[pix + 1])
                            {
                                gmax = g_PixBytes[pix + 1];
                                gmaxind = gmax;
                            }
                            if (bmax > g_PixBytes[pix + 0])
                            {
                                bmax = g_PixBytes[pix + 0];
                                bmaxind = bmax;
                            }
                        }

                        pix = y * newData.Stride + 3 * x;

                        g_OutBytes[pix + 2] = (byte)rmaxind;
                        g_OutBytes[pix + 1] = (byte)gmaxind;
                        g_OutBytes[pix + 0] = (byte)bmaxind;
                    }
                }
            });

            Marshal.Copy(g_OutBytes, 0, newData.Scan0, total_size);
            bmp.UnlockBits(newData);
            kernel1 = null;
            g_PixBytes = null;
            g_OutBytes = null;

        }
        //uses of erode bitmap
        private void button3_Click(object sender, EventArgs e)
        {
            Bitmap bmp = new Bitmap(@"C:\test.bmp");
            //Erode(ref bmp, 1);
            Dilate(ref bmp, 1);
            pictureBox1.Image = bmp;
        }










        //denoise image with radius and sigma-----------------------------------------------------------------------------
        private void button4_Click(object sender, EventArgs e)
        {
            Bitmap bmp = new Bitmap(@"C:\test.bmp");


            BitmapData newData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            byte[] g_PixBytes = null;
            byte[] g_outBytes = null;
            int total_size = newData.Stride * newData.Height;
            g_PixBytes = new byte[total_size + 1];
            g_outBytes = new byte[total_size + 1];


            Marshal.Copy(newData.Scan0, g_PixBytes, 0, total_size);
            Array.Copy(g_PixBytes, g_outBytes, g_PixBytes.Length);

            int width = bmp.Width;
            int height = bmp.Height;


            int Nh = 6;               //radius
            int sigma = 20;           //must be an integer 0<=sigma<=255

            for (int x1 = Nh; x1 < width - Nh; x1++)
            {
                for (int y1 = Nh; y1 < height - Nh; y1++)
                {
                    int xx, xxx, yy, yyy;
                    double r, g, b, sumR, sumG, sumB, countR, countG, countB;
                    double Rf, Gf, Bf;

                    sumR = sumG = sumB = countR = countG = countB = 0;
                    for (yy = -Nh; yy <= Nh; yy++)
                    {
                        yyy = y1 + yy;
                        for (xx = -Nh; xx <= Nh; xx++)
                        {
                            xxx = x1 + xx;

                            int pix1 = 0;
                            int pix2 = 0;
                            pix1 = yyy * newData.Stride + 3 * xxx;
                            r = g_PixBytes[pix1 + 2];
                            g = g_PixBytes[pix1 + 1];
                            b = g_PixBytes[pix1 + 0];

                            pix2 = y1 * newData.Stride + 3 * x1;

                            if (Math.Abs(g_PixBytes[pix2 + 2] - r) <= sigma)
                            {
                                sumR += r;
                                countR++;
                            }
                            if (Math.Abs(g_PixBytes[pix2 + 1] - g) <= sigma)
                            {
                                sumG += g;
                                countG++;
                            }
                            if (Math.Abs(g_PixBytes[pix2 + 0] - b) <= sigma)
                            {
                                sumB += b;
                                countB++;
                            }
                        }
                    }

                    Rf = sumR / countR;
                    Gf = sumG / countG;
                    Bf = sumB / countB;

                    int pix3 = 0;
                    pix3 = y1 * newData.Stride + 3 * x1;

                    g_outBytes[pix3 + 2] = (byte)Rf;
                    g_outBytes[pix3 + 1] = (byte)Gf;
                    g_outBytes[pix3 + 0] = (byte)Bf;


                }
            }


            Marshal.Copy(g_outBytes, 0, newData.Scan0, total_size);

            bmp.UnlockBits(newData);
            g_PixBytes = null;
            g_outBytes = null;

            pictureBox1.Image = bmp;

        }






        //Convert color to prgb and back----------------------------------------------------------------------
        private void button5_Click(object sender, EventArgs e)
        {
            byte color = 210;
            byte alpha = 100;

            byte ret = PremultiplyAlphaTonormal(PremultiplyAlpha_Component(color, alpha), alpha);
            MessageBox.Show(ret.ToString());
        }
        private double PremultiplyAlpha_Component(double sourceColor, double alpha)
        {
            return ((sourceColor * alpha) / 255d);
        }
        private byte PremultiplyAlphaTonormal(double sourceColor, double alpha)
        {
            return (byte)(sourceColor / (alpha / 255d));
        }












    }
}

Download Code