예제 #1
0
        /// <summary>
        /// Run a basic Anti-Aliasing Algorithm on the specified image.
        /// </summary>
        /// <param name="o">The image to Anti-Alias.</param>
        /// <returns>The Anti-Aliased Image.</returns>
        public static Image AntiAlias(Image i)
        {
            Image o = new Image(i.Width, i.Height);

            for (uint y = 0; y < i.Height; y++)
            {
                for (uint x = 0; x < i.Width; x++)
                {
                    uint  R = 0, G = 0, B = 0;
                    byte  divBy = 0;
                    Pixel p     = i.GetPixel(x, y);
                    R += p.R;
                    G += p.G;
                    B += p.B;
                    divBy++;

                    p = i.GetPixel(x - 1, y - 1);
                    if (!p.Empty)
                    {
                        R += p.R;
                        G += p.G;
                        B += p.B;
                        divBy++;
                    }

                    p = i.GetPixel(x, y - 1);
                    if (!p.Empty)
                    {
                        R += p.R;
                        G += p.G;
                        B += p.B;
                        divBy++;
                    }

                    p = i.GetPixel(x + 1, y - 1);
                    if (!p.Empty)
                    {
                        R += p.R;
                        G += p.G;
                        B += p.B;
                        divBy++;
                    }

                    p = i.GetPixel(x - 1, y);
                    if (!p.Empty)
                    {
                        R += p.R;
                        G += p.G;
                        B += p.B;
                        divBy++;
                    }

                    p = i.GetPixel(x + 1, y);
                    if (!p.Empty)
                    {
                        R += p.R;
                        G += p.G;
                        B += p.B;
                        divBy++;
                    }

                    p = i.GetPixel(x - 1, y + 1);
                    if (!p.Empty)
                    {
                        R += p.R;
                        G += p.G;
                        B += p.B;
                        divBy++;
                    }

                    p = i.GetPixel(x, y + 1);
                    if (!p.Empty)
                    {
                        R += p.R;
                        G += p.G;
                        B += p.B;
                        divBy++;
                    }

                    p = i.GetPixel(x + 1, y + 1);
                    if (!p.Empty)
                    {
                        R += p.R;
                        G += p.G;
                        B += p.B;
                        divBy++;
                    }

                    o.SetPixel(x, y, new Pixel(((byte)(R / divBy)), ((byte)(G / divBy)), ((byte)(B / divBy)), 255));
                }
            }
            i.Dispose();
            return(o);
        }
예제 #2
0
        private static Image ResizeBicubic(Image i, Vec2 outSize)
        {
            Image o = new Image(outSize.X, outSize.Y);

            int height = i.Height,
                width = i.Width,
                newHeight = o.Height,
                newWidth = o.Width,
                ymax = height - 1,
                xmax = width - 1,
                ox1, oy1, ox2, oy2;
            double xFactor = (double)width / newWidth,
                   yFactor = (double)height / newHeight,
                   ox, oy, dx, dy, k1, k2, r, g, b, a,
                   x8, a2, b2, c2, d2, xm1, xp1, xp2;

            for (int y = 0; y < newHeight; y++)
            {
                oy  = (double)y * yFactor - 0.5f;
                oy1 = (int)oy;
                dy  = oy - (double)oy1;

                for (int x = 0; x < newWidth; x++)
                {
                    ox  = (double)x * xFactor - 0.5f;
                    ox1 = (int)ox;
                    dx  = ox - (double)ox1;

                    r = g = b = a = 0;

                    for (int n = -1; n < 3; n++)
                    {
                        x8 = dy - (double)n;
                        if (x8 > 2.0)
                        {
                            k1 = 0.0;
                        }
                        else
                        {
                            xm1 = x8 - 1.0;
                            xp1 = x8 + 1.0;
                            xp2 = x8 + 2.0;
                            a2  = (xp2 <= 0.0) ? 0.0 : xp2 * xp2 * xp2;
                            b2  = (xp1 <= 0.0) ? 0.0 : xp1 * xp1 * xp1;
                            c2  = (x8 <= 0.0) ? 0.0 : x8 * x8 * x8;
                            d2  = (xm1 <= 0.0) ? 0.0 : xm1 * xm1 * xm1;
                            k1  = (0.16666666666666666667 * (a2 - (4.0 * b2) + (6.0 * c2) - (4.0 * d2)));
                        }


                        oy2 = oy1 + n;
                        if (oy2 < 0)
                        {
                            oy2 = 0;
                        }
                        if (oy2 > ymax)
                        {
                            oy2 = ymax;
                        }

                        for (int m = -1; m < 3; m++)
                        {
                            x8 = (double)m - dx;
                            if (x8 > 2.0)
                            {
                                k2 = 0.0;
                            }
                            else
                            {
                                xm1 = x8 - 1.0;
                                xp1 = x8 + 1.0;
                                xp2 = x8 + 2.0;
                                a2  = (xp2 <= 0.0) ? 0.0 : xp2 * xp2 * xp2;
                                b2  = (xp1 <= 0.0) ? 0.0 : xp1 * xp1 * xp1;
                                c2  = (x8 <= 0.0) ? 0.0 : x8 * x8 * x8;
                                d2  = (xm1 <= 0.0) ? 0.0 : xm1 * xm1 * xm1;
                                k2  = k1 * (0.16666666666666666667 * (a2 - (4.0 * b2) + (6.0 * c2) - (4.0 * d2)));
                            }

                            ox2 = ox1 + m;
                            if (ox2 < 0)
                            {
                                ox2 = 0;
                            }
                            if (ox2 > xmax)
                            {
                                ox2 = xmax;
                            }

                            Pixel srcPixel = i.GetPixel((uint)ox2, (uint)oy2);

                            r += k2 * srcPixel.R;
                            g += k2 * srcPixel.G;
                            b += k2 * srcPixel.B;
                            a += k2 * srcPixel.A;
                        }
                    }
                    o.SetPixel((uint)x, (uint)y, new Pixel((byte)r, (byte)g, (byte)b, (byte)a));
                }
            }

            return(o);
        }
예제 #3
0
파일: Image.cs 프로젝트: zer09/Cosmos
 /// <summary>
 /// Draw a triangle's outline.
 /// </summary>
 /// <param name="p1">The first point of the triangle.</param>
 /// <param name="p2">The second point of the triangle.</param>
 /// <param name="p3">The third point of the triangle.</param>
 /// <param name="color">The color to draw in.</param>
 public void DrawTriangleOutline(Vec2 p1, Vec2 p2, Vec2 p3, Pixel color)
 {
     DrawLines(new Vec2[] { p1, p2, p3, p1 }, color);
 }
예제 #4
0
파일: Image.cs 프로젝트: zer09/Cosmos
        /// <summary>
        /// Implements a flood fill algorithm.
        /// </summary>
        /// <param name="startPoint">The point to start filling from.</param>
        /// <param name="sColor">The color to search for.</param>
        /// <param name="dColor">The color to change it to.</param>
        public void FloodFill(Vec2 startPoint, Pixel sColor, Pixel dColor)
        {
            int x = startPoint.X;
            int y = startPoint.Y;

            if ((GetPixel((uint)x, (uint)y).Empty) || GetPixel((uint)x, (uint)y) == sColor)
            {
                SetPixel((uint)x, (uint)y, dColor);
            }
            Stack <Vec2> q = new Stack <Vec2>();

            Visiteds = new bool[(Height + 1) * (Width + 1)];

            #region Setup Start of queue
            Pixel p;
            Vec2  v;
            p = GetPixel((uint)x + 1, (uint)y);
            if ((p.Empty || p == sColor) && p != dColor)
            {
                v = new Vec2(x + 1, y);
                q.Push(v);
                Visiteds[((y * Width) + x + 1)] = true;
                SetPixel((uint)x + 1, (uint)y, dColor);
            }
            p = GetPixel((uint)x, (uint)y + 1);
            if ((p.Empty || p == sColor) && p != dColor)
            {
                v = new Vec2(x, y + 1);
                q.Push(v);
                Visiteds[(((y + 1) * Width) + x)] = true;
                SetPixel((uint)x, (uint)y + 1, dColor);
            }
            p = GetPixel((uint)x - 1, (uint)y);
            if ((p.Empty || p == sColor) && p != dColor)
            {
                v = new Vec2(x - 1, y);
                q.Push(v);
                Visiteds[((y * Width) + x - 1)] = true;
                SetPixel((uint)(x - 1), (uint)y, dColor);
            }
            p = GetPixel((uint)x, (uint)y - 1);
            if ((p.Empty || p == sColor) && p != dColor)
            {
                v = new Vec2(x, y - 1);
                q.Push(v);
                Visiteds[(((y - 1) * Width) + x)] = true;
                SetPixel((uint)x, (uint)(y - 1), dColor);
            }
            #endregion

            while (q.Count > 0)
            {
                v = q.Pop();
                x = v.X;
                y = v.Y;
                #region Check

                p = GetPixel((uint)x + 1, (uint)y);
                if (p != dColor && (p.Empty || p == sColor))
                {
                    v = new Vec2(x + 1, y);
                    if (x >= 0 && !(Visited(y, x + 1)))
                    {
                        q.Push(v);
                        Visiteds[((y * Width) + x + 1)] = true;
                        SetPixel((uint)x + 1, (uint)y, dColor);
                    }
                }
                p = GetPixel((uint)x, (uint)y + 1);
                if (p != dColor && (p.Empty || p == sColor))
                {
                    v = new Vec2(x, y + 1);
                    if (x >= 0 && !(Visited(y + 1, x)))
                    {
                        q.Push(v);
                        Visiteds[(((y + 1) * Width) + x)] = true;
                        SetPixel((uint)x, (uint)y + 1, dColor);
                    }
                }
                p = GetPixel((uint)x - 1, (uint)y);
                if (p != dColor && (p.Empty || p == sColor))
                {
                    v = new Vec2(x - 1, y);
                    if (x >= 0 && !(Visited(y, x - 1)))
                    {
                        q.Push(v);
                        Visiteds[((y * Width) + x - 1)] = true;
                        SetPixel((uint)x - 1, (uint)y, dColor);
                    }
                }
                p = GetPixel((uint)x, (uint)y - 1);
                if (p != dColor && (p.Empty || p == sColor))
                {
                    v = new Vec2(x, y - 1);
                    if (!(Visited(y - 1, x)))
                    {
                        q.Push(v);
                        Visiteds[(((y - 1) * Width) + x)] = true;
                        SetPixel((uint)x, (uint)y - 1, dColor);
                    }
                }
                #endregion
            }
            // And finally empty the visiteds array.
            Visiteds = new bool[0];
        }
예제 #5
0
파일: Image.cs 프로젝트: zer09/Cosmos
        /// <summary>
        /// Draws a triangle and fills it in.
        /// </summary>
        /// <param name="p1">The first point of the triangle.</param>
        /// <param name="p2">The second point of the triangle.</param>
        /// <param name="p3">The third point of the triangle.</param>
        /// <param name="color">The color to draw in.</param>
        public void DrawTriangle(Vec2 p1, Vec2 p2, Vec2 p3, Pixel color)
        {
            int l; // The farthest left
            int r;
            int t;
            int b;

            #region Organize points
            if (p1.Y > p2.Y && p1.Y > p3.Y)
            {
                t = p1.Y;
                if (p2.Y < p3.Y)
                {
                    b = p2.Y;
                }
                else
                {
                    b = p3.Y;
                }
            }
            else if (p2.Y > p1.Y && p2.Y > p3.Y)
            {
                t = p2.Y;
                if (p1.Y < p3.Y)
                {
                    b = p1.Y;
                }
                else
                {
                    b = p3.Y;
                }
            }
            else // This means p3 is the highest point
            {
                t = p3.Y;
                if (p1.Y < p2.Y)
                {
                    b = p1.Y;
                }
                else
                {
                    b = p2.Y;
                }
            }

            // Now organize in the width direction.
            if (p1.X > p3.X && p1.X > p2.X)
            {
                l = p1.X;
                if (p2.X < p3.X)
                {
                    r = p2.X;
                }
                else
                {
                    r = p3.X;
                }
            }
            else if (p2.X > p3.X && p2.X > p1.X)
            {
                l = p2.X;
                if (p1.X < p3.X)
                {
                    r = p1.X;
                }
                else
                {
                    r = p3.X;
                }
            }
            else
            {
                l = p3.X;
                if (p2.X < p1.X)
                {
                    r = p2.X;
                }
                else
                {
                    r = p1.X;
                }
            }
            #endregion
            int h;
            int w;
            if (t - b + 1 > 0)
            {
                h = t - b + 1;
            }
            else
            {
                h = b - t + 1;
            }
            if (l - r + 1 > 0)
            {
                w = l - r + 1;
            }
            else
            {
                w = r - l + 1;
            }
            Image i = new Image(w, h);
            // Get the location of the points within the image.
            Vec2 p4 = new Vec2(p1.X - r, p1.Y - b);
            Vec2 p5 = new Vec2(p2.X - r, p2.Y - b);
            Vec2 p6 = new Vec2(p3.X - r, p3.Y - b);
#if DebugDraw
            Pixel p9 = new Pixel();
            p9.B = 200;
            i.DrawLine(p4, p5, p9);
            i.DrawLine(p5, p6, p9);
            i.DrawLine(p6, p4, p9);
#else
            i.DrawLine(p4, p5, color);
            i.DrawLine(p5, p6, color);
            i.DrawLine(p6, p4, color);
#endif
            Vec2 center = (p4 + p5 + p6) / 3;
            i.FloodFill(center, new Pixel(true), color);

            /*
             *
             * NOTE TO SELF: Draw a line from each corner to the middle of the opposite line,
             *            so as to fill in the holes that this flood fill method might leave,
             *            when dealing with small angles. Some acute triangles have this problem.
             *
             */
            Vec2 m1 = (p4 + p5) / 2;
            Vec2 m2 = (p5 + p6) / 2;
            Vec2 m3 = (p4 + p6) / 2;
#if DebugDraw
            Pixel p50 = new Pixel();
            p50.B = 200;
            i.DrawLine(p4, p5, p50);
            i.DrawLine(p5, p6, p50);
            i.DrawLine(p6, p4, p50);
#else
            i.DrawLine(p6, m1, color);
            i.DrawLine(p4, m2, color);
            i.DrawLine(p5, m3, color);
#endif

            Vec2 v = new Vec2(r, b);
            DrawImage(v, i);
        }
예제 #6
0
파일: Image.cs 프로젝트: zer09/Cosmos
 /// <summary>
 /// Draws a triangle with the specified fill color, and the specified border color.
 /// </summary>
 /// <param name="p1">The first point.</param>
 /// <param name="p2">The second point.</param>
 /// <param name="p3">The third point.</param>
 /// <param name="FillColor">The color to fill the triangle with.</param>
 /// <param name="BorderColor">The color to draw the border of the triangle.</param>
 public void DrawTriangle(Vec2 p1, Vec2 p2, Vec2 p3, Pixel FillColor, Pixel BorderColor)
 {
     DrawTriangle(p1, p2, p3, FillColor);
     DrawTriangleOutline(p1, p2, p3, BorderColor);
 }
예제 #7
0
파일: Image.cs 프로젝트: zer09/Cosmos
 /// <summary>
 /// Draws a quadrilateral with the specified points.
 /// </summary>
 /// <param name="p1">The first point.</param>
 /// <param name="p2">The second point.</param>
 /// <param name="p3">The third point.</param>
 /// <param name="p4">The fourth point.</param>
 /// <param name="color">The color to draw in.</param>
 public void DrawQuad(Vec2 p1, Vec2 p2, Vec2 p3, Vec2 p4, Pixel color)
 {
     DrawPolygon(new Vec2[] { p1, p2, p3, p4 }, color);
 }
예제 #8
0
파일: Image.cs 프로젝트: zer09/Cosmos
        /// <summary>
        /// Draws a polygon with the specified points.
        /// </summary>
        /// <param name="points">The points of the polygon.</param>
        /// <param name="color">The color to draw in.</param>
        public void DrawPolygon(Vec2[] points, Pixel color)
        {
            Vec2[]      contour = points;
            List <Vec2> result  = new List <Vec2>();
            int         cnt     = 0;

            #region Process
            {
#warning TODO: Change these back to floats when their implemented fully.
                double EPSILON = 0.0000000001f;
                int    n       = contour.Length;
                if (n < 3)
                {
                    throw new Exception("Not enough Verticies!");
                }
                int[] V = new int[n];
                int   Area;
                {
                    int    n2 = contour.Length;
                    double A  = 0.0f;
                    for (int p = n2 - 1, q = 0; q < n2; p = q++)
                    {
                        A += contour[p].X * contour[q].Y - contour[q].X * contour[p].Y;
                    }
                    Area = (Int32)(A * 0.5f);
                }
                if (0.0f < Area)
                {
                    for (int v = 0; v < n; v++)
                    {
                        V[v] = v;
                    }
                }
                else
                {
                    for (int v = 0; v < n; v++)
                    {
                        V[v] = (n - 1) - v;
                    }
                }
                int nv    = n;
                int count = 2 * nv;
                for (int m = 0, v = nv - 1; nv > 2;)
                {
                    if (0 >= (count--))
                    {
                        throw new Exception("Invalid polygon!");
                    }
                    int u = v;
                    if (nv <= u)
                    {
                        u = 0;
                    }
                    v = u + 1;
                    if (nv <= v)
                    {
                        v = 0;
                    }
                    int w = v + 1;
                    if (nv <= w)
                    {
                        w = 0;
                    }
                    bool Snip;
                    {
                        int    p;
                        double Ax, Ay, Bx, By, Cx, Cy, Px, Py;
                        Ax = contour[V[u]].X;
                        Ay = contour[V[u]].Y;
                        Bx = contour[V[v]].X;
                        By = contour[V[v]].Y;
                        Cx = contour[V[w]].X;
                        Cy = contour[V[w]].Y;
                        if (EPSILON > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax))))
                        {
                            Snip = false;
                        }
                        for (p = 0; p < nv; p++)
                        {
                            if ((p == u) || (p == v) || (p == w))
                            {
                                continue;
                            }
                            Px = contour[V[p]].X;
                            Py = contour[V[p]].Y;
                            bool InsideTriangle;
                            {
                                double ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
                                double cCROSSap, bCROSScp, aCROSSbp;
                                ax             = Cx - Bx;
                                ay             = Cy - By;
                                bx             = Ax - Cx;
                                by             = Ay - Cy;
                                cx             = Bx - Ax;
                                cy             = By - Ay;
                                apx            = Px - Ax;
                                apy            = Py - Ay;
                                bpx            = Px - Bx;
                                bpy            = Py - By;
                                cpx            = Px - Cx;
                                cpy            = Py - Cy;
                                aCROSSbp       = ax * bpy - ay * bpx;
                                cCROSSap       = cx * apy - cy * apx;
                                bCROSScp       = bx * cpy - by * cpx;
                                InsideTriangle = ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
                            }
                            if (InsideTriangle)
                            {
                                Snip = false;
                            }
                        }
                        Snip = true;
                    }
                    if (Snip)
                    {
                        int a, b, c, s, t;
                        a = V[u];
                        b = V[v];
                        c = V[w];
                        result.Add(contour[a]);
                        result.Add(contour[b]);
                        result.Add(contour[c]);
                        m++;
                        for (s = v, t = v + 1; t < nv; s++, t++)
                        {
                            V[s] = V[t];
                        }
                        nv--;
                        count = 2 * nv;
                    }
                }
            }
            #endregion
            while (cnt < (result.Count / 3))
            {
                DrawTriangle(result[(cnt * 3)], result[(cnt * 3) + 1], result[(cnt * 3) + 2], color);
                cnt++;
            }
        }
예제 #9
0
파일: Image.cs 프로젝트: zer09/Cosmos
 /// <summary>
 /// Draws a quadrilateral with the specified points.
 /// </summary>
 /// <param name="p1">The first point.</param>
 /// <param name="p2">The second point.</param>
 /// <param name="p3">The third point.</param>
 /// <param name="p4">The fourth point.</param>
 /// <param name="FillColor">The color to fill in the rectangle with.</param>
 /// <param name="BorderColor">The color to draw the border in.</param>
 public void DrawQuad(Vec2 p1, Vec2 p2, Vec2 p3, Vec2 p4, Pixel FillColor, Pixel BorderColor)
 {
     DrawPolygon(new Vec2[] { p1, p2, p3, p4 }, FillColor);
     DrawPolygonOutline(new Vec2[] { p1, p2, p3, p4 }, BorderColor);
 }
예제 #10
0
파일: Image.cs 프로젝트: zer09/Cosmos
        /// <summary>
        /// Draws an eliptical arc.
        /// </summary>
        /// <param name="CenterPoint">The center-point of the elipse to use.</param>
        /// <param name="height">The height of the elipse to use.</param>
        /// <param name="width">The width of the elipse to use.</param>
        /// <param name="startAngle">The angle to start drawing at.</param>
        /// <param name="endAngle">The angle to stop drawing at.</param>
        /// <param name="color">The color to draw in.</param>
        public void DrawElipticalArc(Vec2 CenterPoint, int height, int width, int startAngle, int endAngle, Pixel color)
        {
            double angle = (((startAngle <= endAngle) ? startAngle : endAngle) * (Math.PI / 180));
            double range = (((endAngle > startAngle) ? endAngle : startAngle) * (Math.PI / 180));
            double x     = (width * Math.Cos(angle));
            double y     = (height * Math.Sin(angle));

            do
            {
                SetPixel((uint)((int)(CenterPoint.X + x + 0.5)), (uint)((int)(CenterPoint.Y - y + 0.5)), color);
                angle += 0.001;
                x      = (width * Math.Cos(angle));
                y      = (height * Math.Sin(angle));
            }while (angle <= range);
        }
예제 #11
0
파일: Image.cs 프로젝트: zer09/Cosmos
 /// <summary>
 /// Draws an elipse outline.
 /// </summary>
 /// <param name="CenterPoint">The center of the elipse</param>
 /// <param name="height">The height of the elipse.</param>
 /// <param name="width">The width of the elipse.</param>
 /// <param name="color">The color to draw in.</param>
 public void DrawElipseOutline(Vec2 CenterPoint, int height, int width, Pixel color)
 {
     DrawElipticalArc(CenterPoint, height, width, 0, 360, color);
 }
예제 #12
0
파일: Image.cs 프로젝트: zer09/Cosmos
 /// <summary>
 /// Draws and fills an elipse.
 /// </summary>
 /// <param name="CenterPoint">The center of the elipse</param>
 /// <param name="height">The height of the elipse.</param>
 /// <param name="width">The width of the elipse.</param>
 /// <param name="fillColor">The color to fill in.</param>
 /// <param name="borderColor">The color to draw the border in.</param>
 public void DrawElipse(Vec2 CenterPoint, int height, int width, Pixel fillColor, Pixel borderColor)
 {
     DrawElipse(CenterPoint, height, width, fillColor);
     DrawElipseOutline(CenterPoint, height, width, borderColor);
 }
예제 #13
0
파일: Image.cs 프로젝트: zer09/Cosmos
 public void DrawString(Vec2 loc, String s, FontSupport.Font f, int stringHeight, FontSupport.FontStyle flags, Pixel color)
 {
     FontSupport.FontManager.Instance.DrawText(this, null, null, s, f, loc, color);
 }