示例#1
0
        public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
        {
            int   warmth     = Data.Warmth;
            float redAdjust  = 1.0f + (warmth / 100.0f);
            float blueAdjust = 1.0f - (warmth / 100.0f);

            this.blurEffect.Render(src, dest, rois);
            this.bacAdjustment.Render(src, dest, rois);

            foreach (Gdk.Rectangle roi in rois)
            {
                for (int y = roi.Top; y < roi.Bottom; ++y)
                {
                    ColorBgra *srcPtr = src.GetPointAddress(roi.X, y);
                    ColorBgra *dstPtr = dest.GetPointAddress(roi.X, y);

                    for (int x = roi.Left; x < roi.Right; ++x)
                    {
                        ColorBgra srcGrey = this.desaturateOp.Apply(*srcPtr);

                        srcGrey.R = Utility.ClampToByte((int)((float)srcGrey.R * redAdjust));
                        srcGrey.B = Utility.ClampToByte((int)((float)srcGrey.B * blueAdjust));

                        ColorBgra mypixel = this.overlayOp.Apply(srcGrey, *dstPtr);
                        *         dstPtr  = mypixel;

                        ++srcPtr;
                        ++dstPtr;
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Provides a default implementation for performing dst = F(dst, src) or F(src) over some rectangle
        /// of interest. May be slightly faster than calling the other multi-parameter Apply method, as less
        /// variables are used in the implementation, thus inducing less register pressure.
        /// </summary>
        /// <param name="dst">The Surface to write pixels to, and from which pixels are read and used as the lhs parameter for calling the method <b>ColorBgra Apply(ColorBgra, ColorBgra)</b>.</param>
        /// <param name="dstOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the dst Surface.</param>
        /// <param name="src">The Surface to read pixels from for the rhs parameter given to the method <b>ColorBgra Apply(ColorBgra, ColorBgra)</b>b>.</param></param>
        /// <param name="srcOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the src Surface.</param>
        /// <param name="roiSize">The size of the rectangles-of-interest for all Surfaces.</param>
        public void ApplyBase(ImageSurface dst, Gdk.Point dstOffset, ImageSurface src, Gdk.Point srcOffset, Gdk.Size roiSize)
        {
            // Create bounding rectangles for each Surface
            Gdk.Rectangle dstRect = new Gdk.Rectangle(dstOffset, roiSize);

            if (dstRect.Width == 0 || dstRect.Height == 0)
            {
                return;
            }

            Gdk.Rectangle srcRect = new Gdk.Rectangle(srcOffset, roiSize);

            if (srcRect.Width == 0 || srcRect.Height == 0)
            {
                return;
            }

            // Clip those rectangles to those Surface's bounding rectangles
            Gdk.Rectangle dstClip = Gdk.Rectangle.Intersect(dstRect, dst.GetBounds());
            Gdk.Rectangle srcClip = Gdk.Rectangle.Intersect(srcRect, src.GetBounds());

            // If any of those Rectangles actually got clipped, then throw an exception
            if (dstRect != dstClip)
            {
                throw new ArgumentOutOfRangeException
                      (
                          "roiSize",
                          "Destination roi out of bounds" +
                          string.Format(", dst.Size=({0},{1}", dst.Width, dst.Height) +
                          ", dst.Bounds=" + dst.GetBounds().ToString() +
                          ", dstOffset=" + dstOffset.ToString() +
                          string.Format(", src.Size=({0},{1}", src.Width, src.Height) +
                          ", srcOffset=" + srcOffset.ToString() +
                          ", roiSize=" + roiSize.ToString() +
                          ", dstRect=" + dstRect.ToString() +
                          ", dstClip=" + dstClip.ToString() +
                          ", srcRect=" + srcRect.ToString() +
                          ", srcClip=" + srcClip.ToString()
                      );
            }

            if (srcRect != srcClip)
            {
                throw new ArgumentOutOfRangeException("roiSize", "Source roi out of bounds");
            }

            // Cache the width and height properties
            int width  = roiSize.Width;
            int height = roiSize.Height;

            // Do the work.
            unsafe {
                for (int row = 0; row < height; ++row)
                {
                    ColorBgra *dstPtr = dst.GetPointAddress(dstOffset.X, dstOffset.Y + row);
                    ColorBgra *srcPtr = src.GetPointAddress(srcOffset.X, srcOffset.Y + row);
                    Apply(dstPtr, srcPtr, width);
                }
            }
        }
示例#3
0
 private unsafe void ApplyRectangle(ImageSurface surface, Gdk.Rectangle rect)
 {
     for (int y = rect.Left; y <= rect.GetBottom(); ++y)
     {
         ColorBgra *ptr = surface.GetPointAddress(rect.Left, y);
         Apply(ptr, rect.Width);
     }
 }
示例#4
0
        public unsafe override void Render(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.Render(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
 public override void Apply(ImageSurface dst, Gdk.Point dstOffset, ImageSurface src, Gdk.Point srcOffset, int scanLength)
 {
     Apply(dst.GetPointAddress(dstOffset), src.GetPointAddress(srcOffset), scanLength);
 }
示例#6
0
        unsafe public override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            int    width       = src.Width;
            int    height      = src.Height;
            int    r           = Data.Amount;
            Random localRandom = this.random;

            int * intensityCount   = stackalloc int[256];
            uint *avgRed           = stackalloc uint[256];
            uint *avgGreen         = stackalloc uint[256];
            uint *avgBlue          = stackalloc uint[256];
            uint *avgAlpha         = stackalloc uint[256];
            byte *intensityChoices = stackalloc byte[(1 + (r * 2)) * (1 + (r * 2))];

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

            foreach (var rect in rois)
            {
                int rectTop    = rect.Top;
                int rectBottom = rect.GetBottom();
                int rectLeft   = rect.Left;
                int rectRight  = rect.GetRight();

                for (int y = rectTop; y <= rectBottom; ++y)
                {
                    ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y);

                    int top    = y - r;
                    int bottom = y + r + 1;

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

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

                    for (int x = rectLeft; x <= rectRight; ++x)
                    {
                        int intensityChoicesIndex = 0;

                        for (int i = 0; i < 256; ++i)
                        {
                            intensityCount[i] = 0;
                            avgRed[i]         = 0;
                            avgGreen[i]       = 0;
                            avgBlue[i]        = 0;
                            avgAlpha[i]       = 0;
                        }

                        int left  = x - r;
                        int right = x + r + 1;

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

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

                        for (int j = top; j < bottom; ++j)
                        {
                            if (j < 0 || j >= height)
                            {
                                continue;
                            }

                            ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_data_ptr, src_width, left, j);

                            for (int i = left; i < right; ++i)
                            {
                                byte intensity = srcPtr->GetIntensityByte();

                                intensityChoices[intensityChoicesIndex] = intensity;
                                ++intensityChoicesIndex;

                                ++intensityCount[intensity];

                                avgRed[intensity]   += srcPtr->R;
                                avgGreen[intensity] += srcPtr->G;
                                avgBlue[intensity]  += srcPtr->B;
                                avgAlpha[intensity] += srcPtr->A;

                                ++srcPtr;
                            }
                        }

                        int randNum;

                        lock (localRandom) {
                            randNum = localRandom.Next(intensityChoicesIndex);
                        }

                        byte chosenIntensity = intensityChoices[randNum];

                        byte R = (byte)(avgRed[chosenIntensity] / intensityCount[chosenIntensity]);
                        byte G = (byte)(avgGreen[chosenIntensity] / intensityCount[chosenIntensity]);
                        byte B = (byte)(avgBlue[chosenIntensity] / intensityCount[chosenIntensity]);
                        byte A = (byte)(avgAlpha[chosenIntensity] / intensityCount[chosenIntensity]);

                        *dstPtr = ColorBgra.FromBgra(B, G, R, A);
                        ++dstPtr;

                        // prepare the array for the next loop iteration
                        for (int i = 0; i < intensityChoicesIndex; ++i)
                        {
                            intensityChoices[i] = 0;
                        }
                    }
                }
            }
        }
示例#7
0
 public static unsafe ColorBgra *GetPointAddress(this ImageSurface surf, Gdk.Point point)
 {
     return(surf.GetPointAddress(point.X, point.Y));
 }
示例#8
0
        unsafe public override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            double[,] weights = Weights;

            var srcWidth  = src.Width;
            var srcHeight = src.Height;

            ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr;

            foreach (var rect in rois)
            {
                // loop through each line of target rectangle
                for (int y = rect.Top; y < rect.Bottom; ++y)
                {
                    int fyStart = 0;
                    int fyEnd   = 3;

                    if (y == 0)
                    {
                        fyStart = 1;
                    }

                    if (y == srcHeight - 1)
                    {
                        fyEnd = 2;
                    }

                    // loop through each point in the line
                    ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y);

                    for (int x = rect.Left; x < rect.Right; ++x)
                    {
                        int fxStart = 0;
                        int fxEnd   = 3;

                        if (x == 0)
                        {
                            fxStart = 1;
                        }

                        if (x == srcWidth - 1)
                        {
                            fxEnd = 2;
                        }

                        // loop through each weight
                        double sum = 0.0;

                        for (int fy = fyStart; fy < fyEnd; ++fy)
                        {
                            for (int fx = fxStart; fx < fxEnd; ++fx)
                            {
                                double    weight    = weights[fy, fx];
                                ColorBgra c         = src.GetPointUnchecked(src_data_ptr, srcWidth, x - 1 + fx, y - 1 + fy);
                                double    intensity = (double)c.GetIntensityByte();
                                sum += weight * intensity;
                            }
                        }

                        int iSum = (int)sum;
                        iSum += 128;

                        if (iSum > 255)
                        {
                            iSum = 255;
                        }

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

                        *dstPtr = ColorBgra.FromBgra((byte)iSum, (byte)iSum, (byte)iSum, 255);

                        ++dstPtr;
                    }
                }
            }
        }
示例#9
0
        unsafe public void Render(ImageSurface surface, Gdk.Rectangle[] rois)
        {
            byte startAlpha;
            byte endAlpha;

            if (this.alphaOnly)
            {
                ComputeAlphaOnlyValuesFromColors(this.startColor, this.endColor, out startAlpha, out endAlpha);
            }
            else
            {
                startAlpha = this.startColor.A;
                endAlpha   = this.endColor.A;
            }

            surface.Flush();

            ColorBgra *src_data_ptr = (ColorBgra *)surface.DataPtr;
            int        src_width    = surface.Width;

            for (int ri = 0; ri < rois.Length; ++ri)
            {
                Gdk.Rectangle rect = rois[ri];

                if (this.startPoint.X == this.endPoint.X && this.startPoint.Y == this.endPoint.Y)
                {
                    // Start and End point are the same ... fill with solid color.
                    for (int y = rect.Top; y <= rect.GetBottom(); ++y)
                    {
                        ColorBgra *pixelPtr = surface.GetPointAddress(rect.Left, y);

                        for (int x = rect.Left; x <= rect.GetRight(); ++x)
                        {
                            ColorBgra result;

                            if (this.alphaOnly && this.alphaBlending)
                            {
                                byte resultAlpha = (byte)Utility.FastDivideShortByByte((ushort)(pixelPtr->A * endAlpha), 255);
                                result   = *pixelPtr;
                                result.A = resultAlpha;
                            }
                            else if (this.alphaOnly && !this.alphaBlending)
                            {
                                result   = *pixelPtr;
                                result.A = endAlpha;
                            }
                            else if (!this.alphaOnly && this.alphaBlending)
                            {
                                result = this.normalBlendOp.Apply(*pixelPtr, this.endColor);
                                //if (!this.alphaOnly && !this.alphaBlending)
                            }
                            else
                            {
                                result = this.endColor;
                            }

                            *pixelPtr = result;
                            ++pixelPtr;
                        }
                    }
                }
                else
                {
                    var mainrect = rect;
                    Parallel.ForEach(Enumerable.Range(rect.Top, rect.Height),
                                     (y) => ProcessGradientLine(startAlpha, endAlpha, y, mainrect, surface, src_data_ptr, src_width));
                }
            }

            surface.MarkDirty();
            AfterRender();
        }