예제 #1
0
파일: FloodTool.cs 프로젝트: deckarep/Pinta
        public static unsafe void FillStencilByColor(ImageSurface surface, IBitVector2D stencil, ColorBgra cmp, int tolerance, out Rectangle boundingBox)
        {
            int top = int.MaxValue;
            int bottom = int.MinValue;
            int left = int.MaxValue;
            int right = int.MinValue;

            stencil.Clear (false);

            for (int y = 0; y < surface.Height; ++y) {
                bool foundPixelInRow = false;
                ColorBgra* ptr = surface.GetRowAddressUnchecked (y);

                for (int x = 0; x < surface.Width; ++x) {
                    if (CheckColor (cmp, *ptr, tolerance)) {
                        stencil.SetUnchecked (x, y, true);

                        if (x < left) {
                            left = x;
                        }

                        if (x > right) {
                            right = x;
                        }

                        foundPixelInRow = true;
                    }

                    ++ptr;
                }

                if (foundPixelInRow) {
                    if (y < top) {
                        top = y;
                    }

                    if (y >= bottom) {
                        bottom = y;
                    }
                }
            }

            boundingBox = new Rectangle (left, top, right + 1, bottom + 1);
        }
예제 #2
0
        public static unsafe void FillStencilByColor(ImageSurface surface, IBitVector2D stencil, ColorBgra cmp, int tolerance, 
		                                              out Rectangle boundingBox, Gdk.Region limitRegion, bool limitToSelection)
        {
            int top = int.MaxValue;
            int bottom = int.MinValue;
            int left = int.MaxValue;
            int right = int.MinValue;
            Gdk.Rectangle[] scans;

            stencil.Clear (false);

            if (limitToSelection) {
                using (Gdk.Region excluded = Gdk.Region.Rectangle (new Gdk.Rectangle (0, 0, stencil.Width, stencil.Height))) {
                    excluded.Xor (limitRegion);
                    scans = excluded.GetRectangles ();
                }
            } else {
                scans = new Gdk.Rectangle[0];
            }

            foreach (Gdk.Rectangle rect in scans)
                stencil.Set (rect, true);

            for (int y = 0; y < surface.Height; ++y) {
                bool foundPixelInRow = false;
                ColorBgra* ptr = surface.GetRowAddressUnchecked (y);

                for (int x = 0; x < surface.Width; ++x) {
                    if (CheckColor (cmp, *ptr, tolerance)) {
                        stencil.SetUnchecked (x, y, true);

                        if (x < left) {
                            left = x;
                        }

                        if (x > right) {
                            right = x;
                        }

                        foundPixelInRow = true;
                    }

                    ++ptr;
                }

                if (foundPixelInRow) {
                    if (y < top) {
                        top = y;
                    }

                    if (y >= bottom) {
                        bottom = y;
                    }
                }
            }

            foreach (Gdk.Rectangle rect in scans)
                stencil.Set (rect, false);

            boundingBox = new Rectangle (left, top, right - left + 1, bottom - top + 1);
        }
예제 #3
0
        public static unsafe void FillStencilFromPoint(ImageSurface surface, IBitVector2D stencil, Point start, int tolerance, 
		                                                out Rectangle boundingBox, Gdk.Region limitRegion, bool limitToSelection)
        {
            ColorBgra cmp = surface.GetColorBgra (start.X, start.Y);
            int top = int.MaxValue;
            int bottom = int.MinValue;
            int left = int.MaxValue;
            int right = int.MinValue;
            Gdk.Rectangle[] scans;

            stencil.Clear (false);

            if (limitToSelection) {
                using (Gdk.Region excluded = Gdk.Region.Rectangle (new Gdk.Rectangle (0, 0, stencil.Width, stencil.Height))) {
                    excluded.Xor (limitRegion);
                    scans = excluded.GetRectangles ();
                }
            } else {
                scans = new Gdk.Rectangle[0];
            }

            foreach (Gdk.Rectangle rect in scans) {
                stencil.Set (rect, true);
            }

            Queue<Point> queue = new Queue<Point> (16);
            queue.Enqueue (start);

            while (queue.Count > 0) {
                Point pt = queue.Dequeue ();

                ColorBgra* rowPtr = surface.GetRowAddressUnchecked (pt.Y);
                int localLeft = pt.X - 1;
                int localRight = pt.X;

                while (localLeft >= 0 &&
                       !stencil.GetUnchecked (localLeft, pt.Y) &&
                       CheckColor (cmp, rowPtr[localLeft], tolerance)) {
                    stencil.SetUnchecked (localLeft, pt.Y, true);
                    --localLeft;
                }

                while (localRight < surface.Width &&
                       !stencil.GetUnchecked (localRight, pt.Y) &&
                       CheckColor (cmp, rowPtr[localRight], tolerance)) {
                    stencil.SetUnchecked (localRight, pt.Y, true);
                    ++localRight;
                }

                ++localLeft;
                --localRight;

                if (pt.Y > 0) {
                    int sleft = localLeft;
                    int sright = localLeft;
                    ColorBgra* rowPtrUp = surface.GetRowAddressUnchecked (pt.Y - 1);

                    for (int sx = localLeft; sx <= localRight; ++sx) {
                        if (!stencil.GetUnchecked (sx, pt.Y - 1) &&
                            CheckColor (cmp, rowPtrUp[sx], tolerance)) {
                            ++sright;
                        } else {
                            if (sright - sleft > 0) {
                                queue.Enqueue (new Point (sleft, pt.Y - 1));
                            }

                            ++sright;
                            sleft = sright;
                        }
                    }

                    if (sright - sleft > 0) {
                        queue.Enqueue (new Point (sleft, pt.Y - 1));
                    }
                }

                if (pt.Y < surface.Height - 1) {
                    int sleft = localLeft;
                    int sright = localLeft;
                    ColorBgra* rowPtrDown = surface.GetRowAddressUnchecked (pt.Y + 1);

                    for (int sx = localLeft; sx <= localRight; ++sx) {
                        if (!stencil.GetUnchecked (sx, pt.Y + 1) &&
                            CheckColor (cmp, rowPtrDown[sx], tolerance)) {
                            ++sright;
                        } else {
                            if (sright - sleft > 0) {
                                queue.Enqueue (new Point (sleft, pt.Y + 1));
                            }

                            ++sright;
                            sleft = sright;
                        }
                    }

                    if (sright - sleft > 0) {
                        queue.Enqueue (new Point (sleft, pt.Y + 1));
                    }
                }

                if (localLeft < left) {
                    left = localLeft;
                }

                if (localRight > right) {
                    right = localRight;
                }

                if (pt.Y < top) {
                    top = pt.Y;
                }

                if (pt.Y > bottom) {
                    bottom = pt.Y;
                }
            }

            foreach (Gdk.Rectangle rect in scans)
                stencil.Set (rect, false);

            boundingBox = new Rectangle (left, top, right - left + 1, bottom - top + 1);
        }
예제 #4
0
        public unsafe override void RenderEffect(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
        {
            // Glow backgound
            glowEffect.Data.Radius = 6;
            glowEffect.Data.Brightness = -(Data.Coloring - 50) * 2;
            glowEffect.Data.Contrast = -(Data.Coloring - 50) * 2;

            this.glowEffect.RenderEffect (src, dest, rois);

            // Create black outlines by finding the edges of objects
            foreach (Gdk.Rectangle roi in rois) {
                for (int y = roi.Top; y < roi.Bottom; ++y) {
                    int top = y - radius;
                    int bottom = y + radius + 1;

                    if (top < 0) {
                        top = 0;
                    }

                    if (bottom > dest.Height) {
                        bottom = dest.Height;
                    }

                    ColorBgra* srcPtr = src.GetPointAddress (roi.X, y);
                    ColorBgra* dstPtr = dest.GetPointAddress (roi.X, y);

                    for (int x = roi.Left; x < roi.Right; ++x) {
                        int left = x - radius;
                        int right = x + radius + 1;

                        if (left < 0) {
                            left = 0;
                        }

                        if (right > dest.Width) {
                            right = dest.Width;
                        }

                        int r = 0;
                        int g = 0;
                        int b = 0;

                        int src_width = src.Width;
                        ColorBgra* src_dataptr = (ColorBgra*)src.DataPtr;

                        for (int v = top; v < bottom; v++) {
                            ColorBgra* pRow = src.GetRowAddressUnchecked (src_dataptr, src_width, v);
                            int j = v - y + radius;

                            for (int u = left; u < right; u++) {
                                int i1 = u - x + radius;
                                int w = conv[j][i1];

                                ColorBgra* pRef = pRow + u;

                                r += pRef->R * w;
                                g += pRef->G * w;
                                b += pRef->B * w;
                            }
                        }

                        ColorBgra topLayer = ColorBgra.FromBgr (
                            Utility.ClampToByte (b),
                            Utility.ClampToByte (g),
                            Utility.ClampToByte (r));

                        // Desaturate
                        topLayer = this.desaturateOp.Apply (topLayer);

                        // Adjust Brightness and Contrast
                        if (topLayer.R > (Data.InkOutline * 255 / 100)) {
                            topLayer = ColorBgra.FromBgra (255, 255, 255, topLayer.A);
                        } else {
                            topLayer = ColorBgra.FromBgra (0, 0, 0, topLayer.A);
                        }

                        // Change Blend Mode to Darken
                        ColorBgra myPixel = this.darkenOp.Apply (topLayer, *dstPtr);
                        *dstPtr = myPixel;

                        ++srcPtr;
                        ++dstPtr;
                    }
                }
            }
        }
예제 #5
0
파일: FloodTool.cs 프로젝트: deckarep/Pinta
        public static unsafe void FillStencilFromPoint(ImageSurface surface, IBitVector2D stencil, Point start, int tolerance, out Rectangle boundingBox)
        {
            ColorBgra cmp = surface.GetColorBgra (start.X, start.Y);
            int top = int.MaxValue;
            int bottom = int.MinValue;
            int left = int.MaxValue;
            int right = int.MinValue;

            stencil.Clear (false);

            Queue<Point> queue = new Queue<Point> (16);
            queue.Enqueue (start);

            while (queue.Count > 0) {
                Point pt = queue.Dequeue ();

                ColorBgra* rowPtr = surface.GetRowAddressUnchecked (pt.Y);
                int localLeft = pt.X - 1;
                int localRight = pt.X;

                while (localLeft >= 0 &&
                       !stencil.GetUnchecked (localLeft, pt.Y) &&
                       CheckColor (cmp, rowPtr[localLeft], tolerance)) {
                    stencil.SetUnchecked (localLeft, pt.Y, true);
                    --localLeft;
                }

                while (localRight < surface.Width &&
                       !stencil.GetUnchecked (localRight, pt.Y) &&
                       CheckColor (cmp, rowPtr[localRight], tolerance)) {
                    stencil.SetUnchecked (localRight, pt.Y, true);
                    ++localRight;
                }

                ++localLeft;
                --localRight;

                if (pt.Y > 0) {
                    int sleft = localLeft;
                    int sright = localLeft;
                    ColorBgra* rowPtrUp = surface.GetRowAddressUnchecked (pt.Y - 1);

                    for (int sx = localLeft; sx <= localRight; ++sx) {
                        if (!stencil.GetUnchecked (sx, pt.Y - 1) &&
                            CheckColor (cmp, rowPtrUp[sx], tolerance)) {
                            ++sright;
                        } else {
                            if (sright - sleft > 0) {
                                queue.Enqueue (new Point (sleft, pt.Y - 1));
                            }

                            ++sright;
                            sleft = sright;
                        }
                    }

                    if (sright - sleft > 0) {
                        queue.Enqueue (new Point (sleft, pt.Y - 1));
                    }
                }

                if (pt.Y < surface.Height - 1) {
                    int sleft = localLeft;
                    int sright = localLeft;
                    ColorBgra* rowPtrDown = surface.GetRowAddressUnchecked (pt.Y + 1);

                    for (int sx = localLeft; sx <= localRight; ++sx) {
                        if (!stencil.GetUnchecked (sx, pt.Y + 1) &&
                            CheckColor (cmp, rowPtrDown[sx], tolerance)) {
                            ++sright;
                        } else {
                            if (sright - sleft > 0) {
                                queue.Enqueue (new Point (sleft, pt.Y + 1));
                            }

                            ++sright;
                            sleft = sright;
                        }
                    }

                    if (sright - sleft > 0) {
                        queue.Enqueue (new Point (sleft, pt.Y + 1));
                    }
                }

                if (localLeft < left) {
                    left = localLeft;
                }

                if (localRight > right) {
                    right = localRight;
                }

                if (pt.Y < top) {
                    top = pt.Y;
                }

                if (pt.Y > bottom) {
                    bottom = pt.Y;
                }
            }

            boundingBox = new Rectangle (left, top, right + 1, bottom + 1);
        }