コード例 #1
0
        private void DrawGradient(Graphics g)
        {
            g.PixelOffsetMode = PixelOffsetMode.Half;
            Rectangle gradientRect;

            float gradientAngle;

            switch (this.orientation)
            {
            case Orientation.Horizontal:
                gradientAngle = 180.0f;
                break;

            case Orientation.Vertical:
                gradientAngle = 90.0f;
                break;

            default:
                throw new InvalidEnumArgumentException();
            }

            // draw gradient
            gradientRect = ClientRectangle;

            switch (this.orientation)
            {
            case Orientation.Horizontal:
                gradientRect.Inflate(-triangleHalfLength, -triangleSize + 3);
                break;

            case Orientation.Vertical:
                gradientRect.Inflate(-triangleSize + 3, -triangleHalfLength);
                break;

            default:
                throw new InvalidEnumArgumentException();
            }

            if (this.customGradient != null && gradientRect.Width > 1 && gradientRect.Height > 1)
            {
                Surface gradientSurface = new Surface(gradientRect.Width, gradientRect.Height);

                using (RenderArgs ra = new RenderArgs(gradientSurface))
                {
                    Utility.DrawColorRectangle(ra.Graphics, ra.Bounds, Color.Transparent, false);

                    if (Orientation == Orientation.Horizontal)
                    {
                        for (int x = 0; x < gradientSurface.Width; ++x)
                        {
                            // TODO: refactor, double buffer, save this computation in a bitmap somewhere
                            double index  = (double)(x * (this.customGradient.Length - 1)) / (double)(gradientSurface.Width - 1);
                            int    indexL = (int)Math.Floor(index);
                            double t      = 1.0 - (index - indexL);
                            int    indexR = (int)Math.Min(this.customGradient.Length - 1, Math.Ceiling(index));
                            Color  colorL = this.customGradient[indexL];
                            Color  colorR = this.customGradient[indexR];

                            double a1 = colorL.A / 255.0;
                            double r1 = colorL.R / 255.0;
                            double g1 = colorL.G / 255.0;
                            double b1 = colorL.B / 255.0;

                            double a2 = colorR.A / 255.0;
                            double r2 = colorR.R / 255.0;
                            double g2 = colorR.G / 255.0;
                            double b2 = colorR.B / 255.0;

                            double at = (t * a1) + ((1.0 - t) * a2);

                            double rt;
                            double gt;
                            double bt;
                            if (at == 0)
                            {
                                rt = 0;
                                gt = 0;
                                bt = 0;
                            }
                            else
                            {
                                rt = ((t * a1 * r1) + ((1.0 - t) * a2 * r2)) / at;
                                gt = ((t * a1 * g1) + ((1.0 - t) * a2 * g2)) / at;
                                bt = ((t * a1 * b1) + ((1.0 - t) * a2 * b2)) / at;
                            }

                            int ap = Utility.Clamp((int)Math.Round(at * 255.0), 0, 255);
                            int rp = Utility.Clamp((int)Math.Round(rt * 255.0), 0, 255);
                            int gp = Utility.Clamp((int)Math.Round(gt * 255.0), 0, 255);
                            int bp = Utility.Clamp((int)Math.Round(bt * 255.0), 0, 255);

                            for (int y = 0; y < gradientSurface.Height; ++y)
                            {
                                ColorBgra src = gradientSurface[x, y];

                                // we are assuming that src.A = 255

                                int rd = ((rp * ap) + (src.R * (255 - ap))) / 255;
                                int gd = ((gp * ap) + (src.G * (255 - ap))) / 255;
                                int bd = ((bp * ap) + (src.B * (255 - ap))) / 255;

                                // TODO: proper alpha blending!
                                gradientSurface[x, y] = ColorBgra.FromBgra((byte)bd, (byte)gd, (byte)rd, 255);
                            }
                        }

                        g.DrawImage(ra.Bitmap, gradientRect, ra.Bounds, GraphicsUnit.Pixel);
                    }
                    else if (Orientation == Orientation.Vertical)
                    {
                        // TODO
                    }
                    else
                    {
                        throw new InvalidEnumArgumentException();
                    }
                }

                gradientSurface.Dispose();
            }
            else
            {
                using (LinearGradientBrush lgb = new LinearGradientBrush(this.ClientRectangle,
                                                                         maxColor, minColor, gradientAngle, false))
                {
                    g.FillRectangle(lgb, gradientRect);
                }
            }

            // fill background
            using (Region nonGradientRegion = new Region())
            {
                nonGradientRegion.MakeInfinite();
                nonGradientRegion.Exclude(gradientRect);

                using (SolidBrush sb = new SolidBrush(this.BackColor))
                {
                    g.FillRegion(sb, nonGradientRegion);
                }
            }

            // draw value triangles
            for (int i = 0; i < this.vals.Length; i++)
            {
                int   pos = ValueToPosition(vals[i]);
                Brush brush;
                Pen   pen;

                if (i == highlight)
                {
                    brush = Brushes.Blue;
                    pen   = (Pen)Pens.White.Clone();
                }
                else
                {
                    brush = Brushes.Black;
                    pen   = (Pen)Pens.Gray.Clone();
                }

                g.SmoothingMode = SmoothingMode.AntiAlias;

                Point a1;
                Point b1;
                Point c1;

                Point a2;
                Point b2;
                Point c2;

                switch (this.orientation)
                {
                case Orientation.Horizontal:
                    a1 = new Point(pos - triangleHalfLength, 0);
                    b1 = new Point(pos, triangleSize - 1);
                    c1 = new Point(pos + triangleHalfLength, 0);

                    a2 = new Point(a1.X, Height - 1 - a1.Y);
                    b2 = new Point(b1.X, Height - 1 - b1.Y);
                    c2 = new Point(c1.X, Height - 1 - c1.Y);
                    break;

                case Orientation.Vertical:
                    a1 = new Point(0, pos - triangleHalfLength);
                    b1 = new Point(triangleSize - 1, pos);
                    c1 = new Point(0, pos + triangleHalfLength);

                    a2 = new Point(Width - 1 - a1.X, a1.Y);
                    b2 = new Point(Width - 1 - b1.X, b1.Y);
                    c2 = new Point(Width - 1 - c1.X, c1.Y);
                    break;

                default:
                    throw new InvalidEnumArgumentException();
                }

                if (this.drawNearNub)
                {
                    g.FillPolygon(brush, new Point[] { a1, b1, c1, a1 });
                }

                if (this.drawFarNub)
                {
                    g.FillPolygon(brush, new Point[] { a2, b2, c2, a2 });
                }

                if (pen != null)
                {
                    if (this.drawNearNub)
                    {
                        g.DrawPolygon(pen, new Point[] { a1, b1, c1, a1 });
                    }

                    if (this.drawFarNub)
                    {
                        g.DrawPolygon(pen, new Point[] { a2, b2, c2, a2 });
                    }

                    pen.Dispose();
                }
            }
        }
コード例 #2
0
 public override ColorBgra Apply(ColorBgra color)
 {
     return(ColorBgra.FromBgra(CurveB[color.B], CurveG[color.G], CurveR[color.R], color.A));
 }
コード例 #3
0
        public override void Render(Surface src, Surface dest, Rectangle[] rois, int startIndex, int length)
        {
            unsafe
            {
                int    w          = dest.Width;
                int    h          = dest.Height;
                double invH       = 1.0 / h;
                double invZoom    = 1.0 / _zoom;
                double invQuality = 1.0 / _quality;
                double aspect     = (double)h / (double)w;
                int    count      = _quality * _quality + 1;
                double invCount   = 1.0 / (double)count;

                for (int ri = startIndex; ri < startIndex + length; ++ri)
                {
                    Rectangle rect = rois[ri];

                    for (int y = rect.Top; y < rect.Bottom; y++)
                    {
                        ColorBgra *dstPtr = dest.GetPointAddressUnchecked(rect.Left, y);

                        for (int x = rect.Left; x < rect.Right; x++)
                        {
                            int r = 0;
                            int g = 0;
                            int b = 0;
                            int a = 0;

                            for (double i = 0; i < count; i++)
                            {
                                double u = (2.0 * x - w + (i * invCount)) * invH;
                                double v = (2.0 * y - h + ((i * invQuality) % 1)) * invH;

                                double radius  = Math.Sqrt((u * u) + (v * v));
                                double radiusP = radius;
                                double theta   = Math.Atan2(v, u);
                                double thetaP  = theta + _angleTheta;

                                double uP = radiusP * Math.Cos(thetaP);
                                double vP = radiusP * Math.Sin(thetaP);

                                double jX = (uP - vP * aspect) * invZoom;
                                double jY = (vP + uP * aspect) * invZoom;

                                double j = Julia(jX, jY, JR, JI);

                                double c = _factor * j;


                                b += PixelUtils.ClampToByte(c - 768);
                                g += PixelUtils.ClampToByte(c - 512);
                                r += PixelUtils.ClampToByte(c - 256);
                                a += PixelUtils.ClampToByte(c - 0);
                            }

                            *dstPtr = ColorBgra.FromBgra(
                                PixelUtils.ClampToByte(b / count),
                                PixelUtils.ClampToByte(g / count),
                                PixelUtils.ClampToByte(r / count),
                                PixelUtils.ClampToByte(a / count));

                            ++dstPtr;
                        }
                    }
                }
            }
        }
コード例 #4
0
            public override ColorBgra Apply(ColorBgra lhs, ColorBgra rhs)
            {
                byte intensityByte = rhs.GetIntensityByte();

                return(ColorBgra.FromBgra(lhs.B, lhs.G, lhs.R, ByteUtil.FastScale(intensityByte, lhs.A)));
            }
コード例 #5
0
 public override ColorBgra Apply(ColorBgra color)
 {
     return(ColorBgra.FromBgra(color.B, color.G, color.R, Curve[color.A]));
 }
コード例 #6
0
 public override ColorBgra Apply(ColorBgra color)
 {
     return(ColorBgra.FromBgra(blueLevels[color.B], greenLevels[color.G], redLevels[color.R], color.A));
 }
コード例 #7
0
ファイル: InkSketchEffect.cs プロジェクト: p07r0457/Pinta
        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;
                    }
                }
            }
        }
コード例 #8
0
        protected unsafe override void OnRender(Rectangle[] rois, int startIndex, int length)
        {
            Surface dst = DstArgs.Surface;
            Surface src = SrcArgs.Surface;

            for (int i = startIndex; i < startIndex + length; ++i)
            {
                Rectangle rect = rois[i];

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

                    if (y == src.Bounds.Top)
                    {
                        fyStart = 1;
                    }

                    if (y == src.Bounds.Bottom - 1)
                    {
                        fyEnd = 2;
                    }

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

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

                        if (x == src.Bounds.Left)
                        {
                            fxStart = 1;
                        }

                        if (x == src.Bounds.Right - 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    = this.weights[fy][fx];
                                ColorBgra c         = src.GetPointUnchecked(x - 1 + fx, y - 1 + fy);
                                double    intensity = (double)c.GetIntensityByte();
                                sum += weight * intensity;
                            }
                        }

                        int iSum = (int)sum + 128;

                        if (iSum > 255)
                        {
                            iSum = 255;
                        }
                        else if (iSum < 0)
                        {
                            iSum = 0;
                        }

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

                        ++dstPtr;
                    }
                }
            }
        }
コード例 #9
0
        unsafe public override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            const double jr = 0.3125;
            const double ji = 0.03;

            int    w          = dst.Width;
            int    h          = dst.Height;
            double invH       = 1.0 / h;
            double invZoom    = 1.0 / Data.Zoom;
            double invQuality = 1.0 / Data.Quality;
            double aspect     = (double)h / (double)w;
            int    count      = Data.Quality * Data.Quality + 1;
            double invCount   = 1.0 / (double)count;
            double angleTheta = (Data.Angle * Math.PI * 2) / 360.0;

            ColorBgra *dst_dataptr = (ColorBgra *)dst.DataPtr;
            int        dst_width   = dst.Width;

            foreach (Gdk.Rectangle rect in rois)
            {
                for (int y = rect.Top; y <= rect.GetBottom(); y++)
                {
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(dst_dataptr, dst_width, rect.Left, y);

                    for (int x = rect.Left; x <= rect.GetRight(); x++)
                    {
                        int r = 0;
                        int g = 0;
                        int b = 0;
                        int a = 0;

                        for (double i = 0; i < count; i++)
                        {
                            double u = (2.0 * x - w + (i * invCount)) * invH;
                            double v = (2.0 * y - h + ((i * invQuality) % 1)) * invH;

                            double radius  = Math.Sqrt((u * u) + (v * v));
                            double radiusP = radius;
                            double theta   = Math.Atan2(v, u);
                            double thetaP  = theta + angleTheta;

                            double uP = radiusP * Math.Cos(thetaP);
                            double vP = radiusP * Math.Sin(thetaP);

                            double jX = (uP - vP * aspect) * invZoom;
                            double jY = (vP + uP * aspect) * invZoom;

                            double j = Julia(jX, jY, jr, ji);

                            double c = Data.Factor * j;

                            b += Utility.ClampToByte(c - 768);
                            g += Utility.ClampToByte(c - 512);
                            r += Utility.ClampToByte(c - 256);
                            a += Utility.ClampToByte(c - 0);
                        }

                        *dstPtr = ColorBgra.FromBgra(Utility.ClampToByte(b / count), Utility.ClampToByte(g / count), Utility.ClampToByte(r / count), Utility.ClampToByte(a / count));

                        ++dstPtr;
                    }
                }
            }
        }
コード例 #10
0
        protected unsafe override void RenderLine(ISurface src, ISurface dst, Rectangle rect)
        {
            if (amount == 0)
            {
                // Copy src to dest
                return;
            }

            var src_bounds = src.Bounds;

            long w   = dst.Width;
            long h   = dst.Height;
            long fox = (long)(dst.Width * offset.X * 32768.0);
            long foy = (long)(dst.Height * offset.Y * 32768.0);
            long fcx = fox + (w << 15);
            long fcy = foy + (h << 15);
            long fz  = amount;

            const int n = 64;

            for (int y = rect.Top; y <= rect.Bottom; ++y)
            {
                ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y);
                ColorBgra *srcPtr = src.GetPointAddress(rect.Left, y);

                for (int x = rect.Left; x <= rect.Right; ++x)
                {
                    long fx = (x << 16) - fcx;
                    long fy = (y << 16) - fcy;

                    int sr = 0;
                    int sg = 0;
                    int sb = 0;
                    int sa = 0;
                    int sc = 0;

                    sr += srcPtr->R * srcPtr->A;
                    sg += srcPtr->G * srcPtr->A;
                    sb += srcPtr->B * srcPtr->A;
                    sa += srcPtr->A;
                    ++sc;

                    for (int i = 0; i < n; ++i)
                    {
                        fx -= ((fx >> 4) * fz) >> 10;
                        fy -= ((fy >> 4) * fz) >> 10;

                        int u = (int)(fx + fcx + 32768 >> 16);
                        int v = (int)(fy + fcy + 32768 >> 16);

                        if (src_bounds.Contains(u, v))
                        {
                            ColorBgra *srcPtr2 = src.GetPointAddress(u, v);

                            sr += srcPtr2->R * srcPtr2->A;
                            sg += srcPtr2->G * srcPtr2->A;
                            sb += srcPtr2->B * srcPtr2->A;
                            sa += srcPtr2->A;
                            ++sc;
                        }
                    }

                    if (sa != 0)
                    {
                        *dstPtr = ColorBgra.FromBgra(
                            Utility.ClampToByte(sb / sa),
                            Utility.ClampToByte(sg / sa),
                            Utility.ClampToByte(sr / sa),
                            Utility.ClampToByte(sa / sc));
                    }
                    else
                    {
                        dstPtr->Bgra = 0;
                    }

                    ++srcPtr;
                    ++dstPtr;
                }
            }
        }
コード例 #11
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            if (Data.Angle == 0)
            {
                // Copy src to dest
                return;
            }

            int w   = dst.Width;
            int h   = dst.Height;
            int fcx = (w << 15) + (int)(Data.Offset.X * (w << 15));
            int fcy = (h << 15) + (int)(Data.Offset.Y * (h << 15));

            int n = (Data.Quality * Data.Quality) * (30 + Data.Quality * Data.Quality);

            int fr = (int)(Data.Angle * Math.PI * 65536.0 / 181.0);

            foreach (Gdk.Rectangle rect in rois)
            {
                for (int y = rect.Top; y < rect.Bottom; ++y)
                {
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
                    ColorBgra *srcPtr = src.GetPointAddressUnchecked(rect.Left, y);

                    for (int x = rect.Left; x < rect.Right; ++x)
                    {
                        int fx = (x << 16) - fcx;
                        int fy = (y << 16) - fcy;

                        int fsr = fr / n;

                        int sr = 0;
                        int sg = 0;
                        int sb = 0;
                        int sa = 0;
                        int sc = 0;

                        sr += srcPtr->R * srcPtr->A;
                        sg += srcPtr->G * srcPtr->A;
                        sb += srcPtr->B * srcPtr->A;
                        sa += srcPtr->A;
                        ++sc;

                        int ox1 = fx;
                        int ox2 = fx;
                        int oy1 = fy;
                        int oy2 = fy;

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

                        for (int i = 0; i < n; ++i)
                        {
                            Rotate(ref ox1, ref oy1, fsr);
                            Rotate(ref ox2, ref oy2, -fsr);

                            int u1 = ox1 + fcx + 32768 >> 16;
                            int v1 = oy1 + fcy + 32768 >> 16;

                            if (u1 > 0 && v1 > 0 && u1 < w && v1 < h)
                            {
                                ColorBgra *sample = src.GetPointAddressUnchecked(src_dataptr, src_width, u1, v1);

                                sr += sample->R * sample->A;
                                sg += sample->G * sample->A;
                                sb += sample->B * sample->A;
                                sa += sample->A;
                                ++sc;
                            }

                            int u2 = ox2 + fcx + 32768 >> 16;
                            int v2 = oy2 + fcy + 32768 >> 16;

                            if (u2 > 0 && v2 > 0 && u2 < w && v2 < h)
                            {
                                ColorBgra *sample = src.GetPointAddressUnchecked(src_dataptr, src_width, u2, v2);

                                sr += sample->R * sample->A;
                                sg += sample->G * sample->A;
                                sb += sample->B * sample->A;
                                sa += sample->A;
                                ++sc;
                            }
                        }

                        if (sa > 0)
                        {
                            *dstPtr = ColorBgra.FromBgra(
                                Utility.ClampToByte(sb / sa),
                                Utility.ClampToByte(sg / sa),
                                Utility.ClampToByte(sr / sa),
                                Utility.ClampToByte(sa / sc));
                        }
                        else
                        {
                            dstPtr->Bgra = 0;
                        }

                        ++dstPtr;
                        ++srcPtr;
                    }
                }
            }
        }
コード例 #12
0
        public unsafe void RenderConvolutionFilter(int[][] weights, int offset, RenderArgs dstArgs, RenderArgs srcArgs,
                                                   Rectangle[] rois, int startIndex, int length)
        {
            int weightsWidth  = weights[0].Length;
            int weightsHeight = weights.Length;

            int fYOffset = -(weightsHeight / 2);
            int fXOffset = -(weightsWidth / 2);

            // we cache the beginning and ending horizontal indices into the weights matrix
            // for every source pixel X location
            // i.e. for src[x,y], where we're concerned with x, what weight[x,y] horizontal
            // extent should we worry about?
            // this way we end up with less branches and faster code (hopefully?!)
            FExtent fxExtent = GetFExtent(srcArgs.Surface.Width, weightsWidth);
            FExtent fyExtent = GetFExtent(srcArgs.Surface.Height, weightsHeight);

            for (int ri = startIndex; ri < startIndex + length; ++ri)
            {
                Rectangle roi = rois[ri];

                for (int y = roi.Top; y < roi.Bottom; ++y)
                {
                    ColorBgra *dstPixel = dstArgs.Surface.GetPointAddressUnchecked(roi.Left, y);
                    int        fyStart  = fyExtent.fStarts[y];
                    int        fyEnd    = fyExtent.fEnds[y];

                    for (int x = roi.Left; x < roi.Right; ++x)
                    {
                        int redSum      = 0;
                        int greenSum    = 0;
                        int blueSum     = 0;
                        int alphaSum    = 0;
                        int colorFactor = 0;
                        int alphaFactor = 0;
                        int fxStart     = fxExtent.fStarts[x];
                        int fxEnd       = fxExtent.fEnds[x];

                        for (int fy = fyStart; fy < fyEnd; ++fy)
                        {
                            int srcY  = y + fy + fYOffset;
                            int srcX1 = x + fXOffset + fxStart;

                            ColorBgra *srcPixel = srcArgs.Surface.GetPointAddressUnchecked(srcX1, srcY);
                            int[]      wRow     = weights[fy];

                            for (int fx = fxStart; fx < fxEnd; ++fx)
                            {
                                int srcX   = fx + srcX1;
                                int weight = wRow[fx];

                                ColorBgra c = *srcPixel;

                                alphaFactor += weight;
                                weight       = weight * (c.A + (c.A >> 7));
                                colorFactor += weight;
                                weight     >>= 8;

                                redSum   += c.R * weight;
                                blueSum  += c.B * weight;
                                greenSum += c.G * weight;
                                alphaSum += c.A * weight;

                                ++srcPixel;
                            }
                        }

                        colorFactor /= 256;

                        if (colorFactor != 0)
                        {
                            redSum   /= colorFactor;
                            greenSum /= colorFactor;
                            blueSum  /= colorFactor;
                        }
                        else
                        {
                            redSum   = 0;
                            greenSum = 0;
                            blueSum  = 0;
                        }

                        if (alphaFactor != 0)
                        {
                            alphaSum /= alphaFactor;
                        }
                        else
                        {
                            alphaSum = 0;
                        }

                        redSum   += offset;
                        greenSum += offset;
                        blueSum  += offset;
                        alphaSum += offset;

                        #region clamp values to [0,255]
                        if (redSum < 0)
                        {
                            redSum = 0;
                        }
                        else if (redSum > 255)
                        {
                            redSum = 255;
                        }

                        if (greenSum < 0)
                        {
                            greenSum = 0;
                        }
                        else if (greenSum > 255)
                        {
                            greenSum = 255;
                        }

                        if (blueSum < 0)
                        {
                            blueSum = 0;
                        }
                        else if (blueSum > 255)
                        {
                            blueSum = 255;
                        }

                        if (alphaSum < 0)
                        {
                            alphaSum = 0;
                        }
                        else if (alphaSum > 255)
                        {
                            alphaSum = 255;
                        }
                        #endregion

                        *dstPixel = ColorBgra.FromBgra((byte)blueSum, (byte)greenSum, (byte)redSum, (byte)alphaSum);
                        ++dstPixel;
                    }
                }
            }
        }
コード例 #13
0
        public unsafe override void Render(EffectConfigToken configToken, RenderArgs dstArgs, RenderArgs srcArgs,
                                           Rectangle[] rois, int startIndex, int length)
        {
            EmbossEffectConfigToken eect = (EmbossEffectConfigToken)configToken;

            double[,] weights = eect.Weights;

            Surface dst = dstArgs.Surface;
            Surface src = srcArgs.Surface;

            for (int i = startIndex; i < startIndex + length; ++i)
            {
                Rectangle rect = rois[i];

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

                    if (y == src.Bounds.Top)
                    {
                        fyStart = 1;
                    }
                    if (y == src.Bounds.Bottom - 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 == src.Bounds.Left)
                        {
                            fxStart = 1;
                        }
                        if (x == src.Bounds.Right - 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(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;
                    }
                }
            }
        }
コード例 #14
0
ファイル: ColorControl.cs プロジェクト: feeleen/pdn-gridwarp
        private void SetSliderGradients()
        {
            HsvColor  h = wheel.HsvColor;
            ColorBgra c = wheel.Color;

            rslider.Gradient = new ColorBgra[] { ColorBgra.FromBgr(c.B, c.G, 0), ColorBgra.FromBgr(c.B, c.G, 255) };
            gslider.Gradient = new ColorBgra[] { ColorBgra.FromBgr(c.B, 0, c.R), ColorBgra.FromBgr(c.B, 255, c.R) };
            bslider.Gradient = new ColorBgra[] { ColorBgra.FromBgr(0, c.G, c.R), ColorBgra.FromBgr(255, c.G, c.R) };
            aslider.Gradient = new ColorBgra[] { ColorBgra.FromBgra(c.B, c.G, c.R, 0), ColorBgra.FromBgra(c.B, c.G, c.R, 255) };

            sslider.Gradient = new ColorBgra[] { new HsvColor(h.Hue, 0, h.Value).ToColorBgra(), new HsvColor(h.Hue, 100, h.Value).ToColorBgra() };
            vslider.Gradient = new ColorBgra[] { new HsvColor(h.Hue, h.Saturation, 0).ToColorBgra(), new HsvColor(h.Hue, h.Saturation, 100).ToColorBgra() };

            if (hslider.Gradient == null)
            {
                ColorBgra[] hues = new ColorBgra[361];
                for (int hue = 0; hue <= 360; ++hue)
                {
                    hues[hue] = new HsvColor(hue, 100, 100).ToColorBgra();
                }
                hslider.Gradient = hues;
            }
        }
コード例 #15
0
        public unsafe void Render(Surface src, Surface dst, Rectangle[] rois, int start, int len)
        {
            int width  = src.Width;
            int height = src.Height;

            int arrayLens = 1 + this.coarseness;

            int localStoreSize = arrayLens * 5 * sizeof(int);

            byte *localStore = stackalloc byte[localStoreSize];
            byte *p          = localStore;

            int *intensityCount = (int *)p;

            p += arrayLens * sizeof(int);

            uint *avgRed = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgGreen = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgBlue = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgAlpha = (uint *)p;

            p += arrayLens * sizeof(uint);

            byte maxIntensity = this.coarseness;

            //TODO: review here
            for (int r = start; r < start + len; ++r)
            {
                Rectangle rect = rois[r];

                int rectTop    = rect.Top;
                int rectBottom = rect.Bottom;
                int rectLeft   = rect.Left;
                int rectRight  = rect.Right;

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

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

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

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

                    for (int x = rectLeft; x < rectRight; ++x)
                    {
                        PlatformMemory.SetToZero(localStore, (ulong)localStoreSize);

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

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

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

                        int numInt = 0;

                        for (int j = top; j < bottom; ++j)
                        {
                            ColorBgra *srcPtr = src.GetPointAddressUnchecked(left, j);

                            for (int i = left; i < right; ++i)
                            {
                                byte intensity = PixelUtils.FastScaleByteByByte(srcPtr->GetIntensityByte(), maxIntensity);

                                ++intensityCount[intensity];
                                ++numInt;

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

                                ++srcPtr;
                            }
                        }

                        byte chosenIntensity = 0;
                        int  maxInstance     = 0;

                        for (int i = 0; i <= maxIntensity; ++i)
                        {
                            if (intensityCount[i] > maxInstance)
                            {
                                chosenIntensity = (byte)i;
                                maxInstance     = intensityCount[i];
                            }
                        }

                        // TODO: correct handling of alpha values?

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

                        *dstPtr = ColorBgra.FromBgra(B, G, R, A);
                        ++dstPtr;
                    }
                }
            }
        }
コード例 #16
0
ファイル: TileEffect.cs プロジェクト: ywscr/Pinta
        unsafe public override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            int   width     = dst.Width;
            int   height    = dst.Height;
            float hw        = width / 2f;
            float hh        = height / 2f;
            float sin       = (float)Math.Sin(Data.Rotation * Math.PI / 180.0);
            float cos       = (float)Math.Cos(Data.Rotation * Math.PI / 180.0);
            float scale     = (float)Math.PI / Data.TileSize;
            float intensity = Data.Intensity;

            intensity = intensity * intensity / 10 * Math.Sign(intensity);

            int     aaLevel   = 4;
            int     aaSamples = aaLevel * aaLevel + 1;
            PointD *aaPoints  = stackalloc PointD[aaSamples];

            for (int i = 0; i < aaSamples; ++i)
            {
                double x = (i * aaLevel) / (double)aaSamples;
                double y = i / (double)aaSamples;

                x -= (int)x;

                // RGSS + rotation to maximize AA quality
                aaPoints[i] = new PointD((double)(cos * x + sin * y), (double)(cos * y - sin * x));
            }

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

            foreach (var rect in rois)
            {
                for (int y = rect.Top; y <= rect.GetBottom(); y++)
                {
                    float      j      = y - hh;
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                    for (int x = rect.Left; x <= rect.GetRight(); x++)
                    {
                        int   b = 0;
                        int   g = 0;
                        int   r = 0;
                        int   a = 0;
                        float i = x - hw;

                        for (int p = 0; p < aaSamples; ++p)
                        {
                            PointD pt = aaPoints[p];

                            float u = i + (float)pt.X;
                            float v = j - (float)pt.Y;

                            float s = cos * u + sin * v;
                            float t = -sin * u + cos * v;

                            s += intensity * (float)Math.Tan(s * scale);
                            t += intensity * (float)Math.Tan(t * scale);
                            u  = cos * s - sin * t;
                            v  = sin * s + cos * t;

                            int xSample = (int)(hw + u);
                            int ySample = (int)(hh + v);

                            xSample = (xSample + width) % width;
                            // This makes it a little faster
                            if (xSample < 0)
                            {
                                xSample = (xSample + width) % width;
                            }

                            ySample = (ySample + height) % height;
                            // This makes it a little faster
                            if (ySample < 0)
                            {
                                ySample = (ySample + height) % height;
                            }

                            ColorBgra sample = *src.GetPointAddressUnchecked(src_data_ptr, src_width, xSample, ySample);

                            b += sample.B;
                            g += sample.G;
                            r += sample.R;
                            a += sample.A;
                        }

                        *(dstPtr++) = ColorBgra.FromBgra((byte)(b / aaSamples), (byte)(g / aaSamples),
                                                         (byte)(r / aaSamples), (byte)(a / aaSamples));
                    }
                }
            }
        }
コード例 #17
0
        public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
        {
            int width  = src.Width;
            int height = src.Height;

            int arrayLens = 1 + Data.Coarseness;

            int localStoreSize = arrayLens * 5 * sizeof(int);

            byte *localStore = stackalloc byte[localStoreSize];
            byte *p          = localStore;

            int *intensityCount = (int *)p;

            p += arrayLens * sizeof(int);

            uint *avgRed = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgGreen = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgBlue = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgAlpha = (uint *)p;

            p += arrayLens * sizeof(uint);

            byte maxIntensity = (byte)Data.Coarseness;

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

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

                for (int y = rectTop; y <= rectBottom; ++y)
                {
                    ColorBgra *dstPtr = dest.GetPointAddressUnchecked(dst_dataptr, dst_width, rect.Left, y);

                    int top    = y - Data.BrushSize;
                    int bottom = y + Data.BrushSize + 1;

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

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

                    for (int x = rectLeft; x <= rectRight; ++x)
                    {
                        SetToZero(localStore, (ulong)localStoreSize);

                        int left  = x - Data.BrushSize;
                        int right = x + Data.BrushSize + 1;

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

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

                        int numInt = 0;

                        for (int j = top; j < bottom; ++j)
                        {
                            ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_dataptr, src_width, left, j);

                            for (int i = left; i < right; ++i)
                            {
                                byte intensity = Utility.FastScaleByteByByte(srcPtr->GetIntensityByte(), maxIntensity);

                                ++intensityCount[intensity];
                                ++numInt;

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

                                ++srcPtr;
                            }
                        }

                        byte chosenIntensity = 0;
                        int  maxInstance     = 0;

                        for (int i = 0; i <= maxIntensity; ++i)
                        {
                            if (intensityCount[i] > maxInstance)
                            {
                                chosenIntensity = (byte)i;
                                maxInstance     = intensityCount[i];
                            }
                        }

                        // TODO: correct handling of alpha values?

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

                        *dstPtr = ColorBgra.FromBgra(B, G, R, A);
                        ++dstPtr;
                    }
                }
            }
        }
コード例 #18
0
        protected unsafe override void RenderLine(ISurface src, ISurface dst, Rectangle rect)
        {
            int    width       = src.Width;
            int    height      = src.Height;
            int    r           = 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 rectTop    = rect.Top;
            int rectBottom = rect.Bottom;
            int rectLeft   = rect.Left;
            int rectRight  = rect.Right;

            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.GetPointAddress(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;
                    }
                }
            }
        }
コード例 #19
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            if (Data.Amount == 0)
            {
                // Copy src to dest
                return;
            }

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

            Gdk.Rectangle src_bounds = src.GetBounds();

            long w   = dst.Width;
            long h   = dst.Height;
            long fox = (long)(dst.Width * Data.Offset.X * 32768.0);
            long foy = (long)(dst.Height * Data.Offset.Y * 32768.0);
            long fcx = fox + (w << 15);
            long fcy = foy + (h << 15);
            long fz  = Data.Amount;

            const int n = 64;

            foreach (Gdk.Rectangle rect in rois)
            {
                for (int y = rect.Top; y <= rect.GetBottom(); ++y)
                {
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(dst_data_ptr, dst_width, rect.Left, y);
                    ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_data_ptr, src_width, rect.Left, y);

                    for (int x = rect.Left; x <= rect.GetRight(); ++x)
                    {
                        long fx = (x << 16) - fcx;
                        long fy = (y << 16) - fcy;

                        int sr = 0;
                        int sg = 0;
                        int sb = 0;
                        int sa = 0;
                        int sc = 0;

                        sr += srcPtr->R * srcPtr->A;
                        sg += srcPtr->G * srcPtr->A;
                        sb += srcPtr->B * srcPtr->A;
                        sa += srcPtr->A;
                        ++sc;

                        for (int i = 0; i < n; ++i)
                        {
                            fx -= ((fx >> 4) * fz) >> 10;
                            fy -= ((fy >> 4) * fz) >> 10;

                            int u = (int)(fx + fcx + 32768 >> 16);
                            int v = (int)(fy + fcy + 32768 >> 16);

                            if (src_bounds.Contains(u, v))
                            {
                                ColorBgra *srcPtr2 = src.GetPointAddressUnchecked(src_data_ptr, src_width, u, v);

                                sr += srcPtr2->R * srcPtr2->A;
                                sg += srcPtr2->G * srcPtr2->A;
                                sb += srcPtr2->B * srcPtr2->A;
                                sa += srcPtr2->A;
                                ++sc;
                            }
                        }

                        if (sa != 0)
                        {
                            *dstPtr = ColorBgra.FromBgra(
                                Utility.ClampToByte(sb / sa),
                                Utility.ClampToByte(sg / sa),
                                Utility.ClampToByte(sr / sa),
                                Utility.ClampToByte(sa / sc));
                        }
                        else
                        {
                            dstPtr->Bgra = 0;
                        }

                        ++srcPtr;
                        ++dstPtr;
                    }
                }
            }
        }
コード例 #20
0
        private ColorBgra ReadColor(Stream input, int pixelDepth, ColorBgra[] palette)
        {
            ColorBgra color;

            switch (pixelDepth)
            {
            case 32:
            {
                long colorInt = Utility.ReadUInt32(input);

                if (colorInt == -1)
                {
                    throw new EndOfStreamException();
                }

                color = ColorBgra.FromUInt32((uint)colorInt);
                break;
            }

            case 24:
            {
                int colorInt = Utility.ReadUInt24(input);

                if (colorInt == -1)
                {
                    throw new EndOfStreamException();
                }

                color   = ColorBgra.FromUInt32((uint)colorInt);
                color.A = 255;
                break;
            }

            case 15:
            case 16:
            {
                int colorWord = Utility.ReadUInt16(input);

                if (colorWord == -1)
                {
                    throw new EndOfStreamException();
                }

                color = ColorBgra.FromBgra(
                    (byte)((colorWord >> 7) & 0xf8),
                    (byte)((colorWord >> 2) & 0xf8),
                    (byte)((colorWord & 0x1f) * 8),
                    255);

                break;
            }

            case 8:
            {
                int colorByte = input.ReadByte();

                if (colorByte == -1)
                {
                    throw new EndOfStreamException();
                }

                if (colorByte >= palette.Length)
                {
                    throw new FormatException("color index was outside the bounds of the palette");
                }

                color = palette[colorByte];
                break;
            }

            default:
                throw new FormatException("colorDepth was not one of {8, 15, 16, 24, 32}");
            }

            return(color);
        }
コード例 #21
0
        public override void Render(Surface src, Surface dst, Rectangle[] rois, int startIndex, int length)
        {
            unsafe
            {
                // Glow backgound
                glowRenderer.Render(src, dst, rois, startIndex, length);

                // Create black outlines by finding the edges of objects

                for (int i = startIndex; i < startIndex + length; ++i)
                {
                    Rectangle roi = rois[i];

                    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 > dst.Height)
                        {
                            bottom = dst.Height;
                        }

                        ColorBgra *srcPtr = src.GetPointAddress(roi.X, y);
                        ColorBgra *dstPtr = src.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 > dst.Width)
                            {
                                right = dst.Width;
                            }

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

                            for (int v = top; v < bottom; v++)
                            {
                                ColorBgra *pRow = src.GetRowAddress(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(
                                PixelUtils.ClampToByte(b),
                                PixelUtils.ClampToByte(g),
                                PixelUtils.ClampToByte(r));

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

                            // Adjust Brightness and Contrast
                            if (topLayer.R > (this.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;
                        }
                    }
                }
            }
        }
コード例 #22
0
        protected override unsafe void OnRender(Rectangle[] renderRects, int startIndex, int length)
        {
            int w = DstArgs.Width;
            int h = DstArgs.Height;

            double wDiv2 = (double)w / 2;
            double hDiv2 = (double)h / 2;

            double invH    = 1.0 / h;
            double invZoom = 1.0 / this.zoom;

            double invQuality = 1.0 / (double)this.quality;

            int    count    = this.quality * this.quality + 1;
            double invCount = 1.0 / (double)count;

            for (int ri = startIndex; ri < startIndex + length; ++ri)
            {
                Rectangle rect = renderRects[ri];

                for (int y = rect.Top; y < rect.Bottom; y++)
                {
                    ColorBgra *dstPtr = DstArgs.Surface.GetPointAddressUnchecked(rect.Left, y);

                    for (int x = rect.Left; x < rect.Right; x++)
                    {
                        int r = 0;
                        int g = 0;
                        int b = 0;
                        int a = 0;

                        for (double i = 0; i < count; i++)
                        {
                            double u = (2.0 * x - w + (i * invCount)) * invH;
                            double v = (2.0 * y - h + ((i * invQuality) % 1)) * invH;

                            double radius  = Math.Sqrt((u * u) + (v * v));
                            double radiusP = radius;
                            double theta   = Math.Atan2(v, u);
                            double thetaP  = theta + this.angleTheta;

                            double uP = radiusP * Math.Cos(thetaP);
                            double vP = radiusP * Math.Sin(thetaP);

                            double m = Mandelbrot(
                                (uP * invZoom) + this.xOffset,
                                (vP * invZoom) + this.yOffset,
                                this.factor);

                            double c = 64 + this.factor * m;

                            r += Utility.ClampToByte(c - 768);
                            g += Utility.ClampToByte(c - 512);
                            b += Utility.ClampToByte(c - 256);
                            a += Utility.ClampToByte(c - 0);
                        }

                        *dstPtr = ColorBgra.FromBgra(
                            Utility.ClampToByte(b / count),
                            Utility.ClampToByte(g / count),
                            Utility.ClampToByte(r / count),
                            Utility.ClampToByte(a / count));

                        ++dstPtr;
                    }
                }

                if (this.invertColors)
                {
                    for (int y = rect.Top; y < rect.Bottom; y++)
                    {
                        ColorBgra *dstPtr = DstArgs.Surface.GetPointAddressUnchecked(rect.Left, y);

                        for (int x = rect.Left; x < rect.Right; ++x)
                        {
                            ColorBgra c = *dstPtr;

                            c.B = (byte)(255 - c.B);
                            c.G = (byte)(255 - c.G);
                            c.R = (byte)(255 - c.R);

                            *dstPtr = c;
                            ++dstPtr;
                        }
                    }
                }
            }
        }
コード例 #23
0
        public unsafe void RenderColorDifferenceEffect(
            double[][] weights,
            RenderArgs dstArgs,
            RenderArgs srcArgs,
            Rectangle[] rois,
            int startIndex,
            int length)
        {
            Surface dst = dstArgs.Surface;
            Surface src = srcArgs.Surface;

            for (int i = startIndex; i < startIndex + length; ++i)
            {
                Rectangle rect = rois[i];

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

                    if (y == src.Bounds.Top)
                    {
                        fyStart = 1;
                    }
                    if (y == src.Bounds.Bottom - 1)
                    {
                        fyEnd = 2;
                    }

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

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

                        if (x == src.Bounds.Left)
                        {
                            fxStart = 1;
                        }

                        if (x == src.Bounds.Right - 1)
                        {
                            fxEnd = 2;
                        }

                        // loop through each weight
                        double rSum = 0.0;
                        double gSum = 0.0;
                        double bSum = 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(x - 1 + fx, y - 1 + fy);

                                rSum += weight * (double)c.R;
                                gSum += weight * (double)c.G;
                                bSum += weight * (double)c.B;
                            }
                        }

                        int iRsum = (int)rSum;
                        int iGsum = (int)gSum;
                        int iBsum = (int)bSum;

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

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

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

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

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

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

                        *dstPtr = ColorBgra.FromBgra((byte)iBsum, (byte)iGsum, (byte)iRsum, 255);
                        ++dstPtr;
                    }
                }
            }
        }
コード例 #24
0
        public static unsafe ColorBgra GetPercentile(int percentile, int area, int *hb, int *hg, int *hr, int *ha)
        {
            int minCount = area * percentile / 100;

            int b      = 0;
            int bCount = 0;

            while (b < 255 && hb[b] == 0)
            {
                ++b;
            }

            while (b < 255 && bCount < minCount)
            {
                bCount += hb[b];
                ++b;
            }

            int g      = 0;
            int gCount = 0;

            while (g < 255 && hg[g] == 0)
            {
                ++g;
            }

            while (g < 255 && gCount < minCount)
            {
                gCount += hg[g];
                ++g;
            }

            int r      = 0;
            int rCount = 0;

            while (r < 255 && hr[r] == 0)
            {
                ++r;
            }

            while (r < 255 && rCount < minCount)
            {
                rCount += hr[r];
                ++r;
            }

            int a      = 0;
            int aCount = 0;

            while (a < 255 && ha[a] == 0)
            {
                ++a;
            }

            while (a < 255 && aCount < minCount)
            {
                aCount += ha[a];
                ++a;
            }

            return(ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, (byte)a));
        }
コード例 #25
0
            public override ColorBgra Apply(ColorBgra color)
            {
                int i = 0;
                int h, s, v, delta;

                switch (InputMode)
                {
                case Channel.A:
                    i = Curve[color.A];
                    break;

                case Channel.R:
                    i = Curve[color.R];
                    break;

                case Channel.G:
                    i = Curve[color.G];
                    break;

                case Channel.B:
                    i = Curve[color.B];
                    break;

                case Channel.C:
                    i  = 255 - color.R;
                    i -= Math.Min(Math.Min(255 - color.R, 255 - color.G), 255 - color.B);
                    i  = Curve[i];
                    break;

                case Channel.M:
                    i  = 255 - color.G;
                    i -= Math.Min(Math.Min(255 - color.R, 255 - color.G), 255 - color.B);
                    i  = Curve[i];
                    break;

                case Channel.Y:
                    i  = 255 - color.B;
                    i -= Math.Min(Math.Min(255 - color.R, 255 - color.G), 255 - color.B);
                    i  = Curve[i];
                    break;

                case Channel.K:
                    i = Math.Min(Math.Min(255 - color.R, 255 - color.G), 255 - color.B);
                    i = Curve[i];
                    break;

                case Channel.H:
                    s     = 0;
                    v     = (color.R > color.G) ? color.R : color.G;
                    delta = 0;
                    if (color.B > v)
                    {
                        v = color.B;
                    }
                    if (v == 0)
                    {
                        s = 0;
                    }
                    else
                    {
                        int min = (color.R < color.G) ? color.R : color.G;
                        if (color.B < min)
                        {
                            min = color.B;
                        }
                        delta = v - min;
                        if (delta > 0)
                        {
                            s = CommonUtil.IntDiv(255 * delta, v);
                        }
                    }
                    if (s == 0)
                    {
                        i = 0;
                    }
                    else
                    {
                        if (color.R == v)     // Between Yellow and Magenta
                        {
                            i = CommonUtil.IntDiv(255 * (color.G - color.B), delta);
                        }
                        else if (color.G == v)     // Between Cyan and Yellow
                        {
                            i = 512 + CommonUtil.IntDiv(255 * (color.B - color.R), delta);
                        }
                        else     // Between Magenta and Cyan
                        {
                            i = 1024 + CommonUtil.IntDiv(255 * (color.R - color.G), delta);
                        }

                        if (i < 0)
                        {
                            i += 1536;
                        }

                        i = CommonUtil.IntDiv(i, 6);
                    }
                    i = Curve[i];
                    break;

                case Channel.S:
                    v = (color.R > color.G) ? color.R : color.G;
                    if (color.B > v)
                    {
                        v = color.B;
                    }
                    if (v == 0)
                    {
                        i = 0;
                    }
                    else
                    {
                        int min = (color.R < color.G) ? color.R : color.G;
                        if (color.B < min)
                        {
                            min = color.B;
                        }
                        delta = v - min;
                        if (delta > 0)
                        {
                            i = CommonUtil.IntDiv(255 * delta, v);
                        }
                    }
                    i = Curve[i];
                    break;

                case Channel.V:
                    i = (color.R > color.G) ? color.R : color.G;
                    if (color.B > i)
                    {
                        i = color.B;
                    }
                    i = Curve[i];
                    break;

                case Channel.L:
                    i = color.GetIntensityByte();
                    i = Curve[i];
                    break;

                default: throw new Exception();
                }
                switch (OutputMode)
                {
                case Channel.A:
                    return(ColorBgra.FromBgra(
                               color.B,
                               color.G,
                               color.R,
                               (byte)i));

                case Channel.R:
                    return(ColorBgra.FromBgra(
                               color.B,
                               color.G,
                               (byte)i,
                               color.A));

                case Channel.G:
                    return(ColorBgra.FromBgra(
                               color.B,
                               (byte)i,
                               color.R,
                               color.A));

                case Channel.B:
                    return(ColorBgra.FromBgra(
                               (byte)i,
                               color.G,
                               color.R,
                               color.A));

                case Channel.C:
                    i = (byte)(i + Math.Min(Math.Min(255 - color.R, 255 - color.G), 255 - color.B)).Clamp(0, 255);
                    return(ColorBgra.FromBgra(
                               color.B,
                               color.G,
                               (byte)(255 - i),
                               color.A));

                case Channel.M:
                    i = (byte)(i + Math.Min(Math.Min(255 - color.R, 255 - color.G), 255 - color.B)).Clamp(0, 255);
                    return(ColorBgra.FromBgra(
                               color.B,
                               (byte)(255 - i),
                               color.R,
                               color.A));

                case Channel.Y:
                    i = (byte)(i + Math.Min(Math.Min(255 - color.R, 255 - color.G), 255 - color.B)).Clamp(0, 255);
                    return(ColorBgra.FromBgra(
                               (byte)(255 - i),
                               color.G,
                               color.R,
                               color.A));

                case Channel.K:
                    int C = 255 - color.R;
                    int M = 255 - color.G;
                    int Y = 255 - color.B;
                    int K = Math.Min(Math.Min(C, M), Y);
                    return(ColorBgra.FromBgraClamped(
                               255 - (Y - K + i),
                               255 - (M - K + i),
                               255 - (C - K + i),
                               color.A));

                case Channel.H:
                    s     = 0;
                    v     = (color.R > color.G) ? color.R : color.G;
                    delta = 0;
                    if (color.B > v)
                    {
                        v = color.B;
                    }
                    if (v == 0)
                    {
                        s = 0;
                    }
                    else
                    {
                        int min = (color.R < color.G) ? color.R : color.G;
                        if (color.B < min)
                        {
                            min = color.B;
                        }
                        delta = v - min;
                        if (delta > 0)
                        {
                            s = CommonUtil.IntDiv(255 * delta, v);
                        }
                    }
                    i *= 6;
                    int fSector = (i & 0xff);
                    int sNumber = (i >> 8);
                    switch (sNumber)
                    {
                    case 0:
                        int tmp0 = ((s * (255 - fSector)) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)(((v * (255 - s)) + 128) >> 8),
                                   (byte)(((v * (255 - tmp0)) + 128) >> 8),
                                   (byte)v,
                                   color.A));

                    case 1:
                        int tmp1 = ((s * fSector) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)(((v * (255 - s)) + 128) >> 8),
                                   (byte)v,
                                   (byte)(((v * (255 - tmp1)) + 128) >> 8),
                                   color.A));

                    case 2:
                        int tmp2 = ((s * (255 - fSector)) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)(((v * (255 - tmp2)) + 128) >> 8),
                                   (byte)v,
                                   (byte)(((v * (255 - s)) + 128) >> 8),
                                   color.A));

                    case 3:
                        int tmp3 = ((s * fSector) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)v,
                                   (byte)(((v * (255 - tmp3)) + 128) >> 8),
                                   (byte)(((v * (255 - s)) + 128) >> 8),
                                   color.A));

                    case 4:
                        int tmp4 = ((s * (255 - fSector)) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)v,
                                   (byte)(((v * (255 - s)) + 128) >> 8),
                                   (byte)(((v * (255 - tmp4)) + 128) >> 8),
                                   color.A));

                    case 5:
                        int tmp5 = ((s * fSector) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)(((v * (255 - tmp5)) + 128) >> 8),
                                   (byte)(((v * (255 - s)) + 128) >> 8),
                                   (byte)v,
                                   color.A));

                    default:
                        return(new ColorBgra());
                    }

                case Channel.S:
                    s     = 0;
                    v     = (color.R > color.G) ? color.R : color.G;
                    delta = 0;
                    if (color.B > v)
                    {
                        v = color.B;
                    }
                    if (v == 0)
                    {
                        s = 0;
                    }
                    else
                    {
                        int min = (color.R < color.G) ? color.R : color.G;
                        if (color.B < min)
                        {
                            min = color.B;
                        }
                        delta = v - min;
                        if (delta > 0)
                        {
                            s = CommonUtil.IntDiv(255 * delta, v);
                        }
                    }
                    if (s == 0)
                    {
                        h = 0;
                    }
                    else
                    {
                        if (color.R == v)     // Between Yellow and Magenta
                        {
                            h = CommonUtil.IntDiv(255 * (color.G - color.B), delta);
                        }
                        else if (color.G == v)     // Between Cyan and Yellow
                        {
                            h = 512 + CommonUtil.IntDiv(255 * (color.B - color.R), delta);
                        }
                        else     // Between Magenta and Cyan
                        {
                            h = 1024 + CommonUtil.IntDiv(255 * (color.R - color.G), delta);
                        }

                        if (h < 0)
                        {
                            h += 1536;
                        }
                    }

                    int fs = (h & 0xff);
                    int sn = (h >> 8);
                    switch (sn)
                    {
                    case 0:
                        int tmp0 = ((i * (255 - fs)) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)(((v * (255 - i)) + 128) >> 8),
                                   (byte)(((v * (255 - tmp0)) + 128) >> 8),
                                   (byte)v,
                                   color.A));

                    case 1:
                        int tmp1 = ((i * fs) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)(((v * (255 - i)) + 128) >> 8),
                                   (byte)v,
                                   (byte)(((v * (255 - tmp1)) + 128) >> 8),
                                   color.A));

                    case 2:
                        int tmp2 = ((i * (255 - fs)) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)(((v * (255 - tmp2)) + 128) >> 8),
                                   (byte)v,
                                   (byte)(((v * (255 - i)) + 128) >> 8),
                                   color.A));

                    case 3:
                        int tmp3 = ((i * fs) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)v,
                                   (byte)(((v * (255 - tmp3)) + 128) >> 8),
                                   (byte)(((v * (255 - i)) + 128) >> 8),
                                   color.A));

                    case 4:
                        int tmp4 = ((i * (255 - fs)) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)v,
                                   (byte)(((v * (255 - i)) + 128) >> 8),
                                   (byte)(((v * (255 - tmp4)) + 128) >> 8),
                                   color.A));

                    case 5:
                        int tmp5 = ((i * fs) + 128) >> 8;
                        return(ColorBgra.FromBgra(
                                   (byte)(((v * (255 - tmp5)) + 128) >> 8),
                                   (byte)(((v * (255 - i)) + 128) >> 8),
                                   (byte)v,
                                   color.A));

                    default:
                        return(new ColorBgra());
                    }

                case Channel.V:
                    int max = (color.R > color.G) ? color.R : color.G;
                    if (color.B > max)
                    {
                        max = color.B;
                    }
                    return(ColorBgra.FromBgra(
                               (byte)CommonUtil.IntDiv(color.B * i, max),
                               (byte)CommonUtil.IntDiv(color.G * i, max),
                               (byte)CommonUtil.IntDiv(color.R * i, max),
                               color.A
                               ));

                case Channel.L:
                    return(ColorBgra.FromBgraClamped(
                               color.B + i - color.GetIntensityByte(),
                               color.G + i - color.GetIntensityByte(),
                               color.R + i - color.GetIntensityByte(),
                               color.A));

                default:
                    throw new Exception();
                }
            }
コード例 #26
0
        public unsafe override ColorBgra Apply(ColorBgra src, int area, int *hb, int *hg, int *hr, int *ha)
        {
            int minCount1 = area * (100 - this.intensity) / 200;
            int minCount2 = area * (100 + this.intensity) / 200;

            int bCount = 0;
            int b1     = 0;

            while (b1 < 255 && hb[b1] == 0)
            {
                ++b1;
            }

            while (b1 < 255 && bCount < minCount1)
            {
                bCount += hb[b1];
                ++b1;
            }

            int b2 = b1;

            while (b2 < 255 && bCount < minCount2)
            {
                bCount += hb[b2];
                ++b2;
            }

            int gCount = 0;
            int g1     = 0;

            while (g1 < 255 && hg[g1] == 0)
            {
                ++g1;
            }

            while (g1 < 255 && gCount < minCount1)
            {
                gCount += hg[g1];
                ++g1;
            }

            int g2 = g1;

            while (g2 < 255 && gCount < minCount2)
            {
                gCount += hg[g2];
                ++g2;
            }

            int rCount = 0;
            int r1     = 0;

            while (r1 < 255 && hr[r1] == 0)
            {
                ++r1;
            }

            while (r1 < 255 && rCount < minCount1)
            {
                rCount += hr[r1];
                ++r1;
            }

            int r2 = r1;

            while (r2 < 255 && rCount < minCount2)
            {
                rCount += hr[r2];
                ++r2;
            }

            int aCount = 0;
            int a1     = 0;

            while (a1 < 255 && hb[a1] == 0)
            {
                ++a1;
            }

            while (a1 < 255 && aCount < minCount1)
            {
                aCount += ha[a1];
                ++a1;
            }

            int a2 = a1;

            while (a2 < 255 && aCount < minCount2)
            {
                aCount += ha[a2];
                ++a2;
            }

            return(ColorBgra.FromBgra(
                       (byte)(255 - (b2 - b1)),
                       (byte)(255 - (g2 - g1)),
                       (byte)(255 - (r2 - r1)),
                       (byte)(a2)));
        }
コード例 #27
0
        public unsafe override void Render(EffectConfigToken properties, RenderArgs dstArgs, RenderArgs srcArgs, 
            Rectangle[] rois, int startIndex, int length)
        {
            TwoAmountsConfigToken token = (TwoAmountsConfigToken)properties;
            int brushSize = token.Amount1;
            byte smoothness = (byte)token.Amount2;
            Surface src = srcArgs.Surface;
            Surface dst = dstArgs.Surface;
            int width = src.Width;
            int height = src.Height;

            int arrayLens = 1 + smoothness;
            int* intensityCount = stackalloc int[arrayLens];
            uint* avgRed = stackalloc uint[arrayLens];
            uint* avgGreen = stackalloc uint[arrayLens];
            uint* avgBlue = stackalloc uint[arrayLens];
            uint* avgAlpha = stackalloc uint[arrayLens];

            byte maxIntensity = smoothness;

            for (int r = startIndex; r < startIndex + length; ++r)
            {
                Rectangle rect = rois[r];

                int rectTop = rect.Top;
                int rectBottom = rect.Bottom;
                int rectLeft = rect.Left;
                int rectRight = rect.Right;

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

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

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

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

                    for (int x = rectLeft; x < rectRight; ++x)
                    {
                        int left = x - brushSize;
                        int right = x + brushSize + 1;

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

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

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

                        int numInt = 0;

                        for (int j = top; j < bottom; ++j)
                        {
                            ColorBgra *srcPtr = src.GetPointAddress(left, j);

                            for (int i = left; i < right; ++i)
                            {
                                byte intensity = (byte)((srcPtr->GetIntensityByte() * maxIntensity) / 255);
                                ++intensityCount[intensity];
                                ++numInt;

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

                                ++srcPtr;
                            }
                        }

                        byte chosenIntensity = 0;
                        int maxInstance = 0;

                        for (int i = 0; i <= maxIntensity; ++i)
                        {
                            if (intensityCount[i] > maxInstance)
                            {
                                chosenIntensity = (byte)i;
                                maxInstance = intensityCount[i];
                            }
                        }

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

                        *dstPtr = ColorBgra.FromBgra(B, G, R, A);
                        ++dstPtr;
                    }
                }
            }
        }
コード例 #28
0
        public override void Render(Surface src, Surface dst, Rectangle[] rois, int startIndex, int length)
        {
            long w   = dst.Width;
            long h   = dst.Height;
            long fox = (long)(dst.Width * offsetX * 32768.0);
            long foy = (long)(dst.Height * offsetY * 32768.0);
            long fcx = fox + (w << 15);
            long fcy = foy + (h << 15);
            long fz  = this.amount;


            unsafe
            {
                for (int r = startIndex; r < startIndex + length; ++r)
                {
                    Rectangle rect = rois[r];

                    for (int y = rect.Top; y < rect.Bottom; ++y)
                    {
                        ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
                        ColorBgra *srcPtr = src.GetPointAddressUnchecked(rect.Left, y);

                        for (int x = rect.Left; x < rect.Right; ++x)
                        {
                            long fx = (x << 16) - fcx;
                            long fy = (y << 16) - fcy;

                            int sr = 0;
                            int sg = 0;
                            int sb = 0;
                            int sa = 0;
                            int sc = 0;

                            sr += srcPtr->R * srcPtr->A;
                            sg += srcPtr->G * srcPtr->A;
                            sb += srcPtr->B * srcPtr->A;
                            sa += srcPtr->A;
                            ++sc;

                            for (int i = 0; i < n; ++i)
                            {
                                fx -= ((fx >> 4) * fz) >> 10;
                                fy -= ((fy >> 4) * fz) >> 10;

                                int u = (int)(fx + fcx + 32768 >> 16);
                                int v = (int)(fy + fcy + 32768 >> 16);

                                if (src.IsVisible(u, v))
                                {
                                    ColorBgra *srcPtr2 = src.GetPointAddressUnchecked(u, v);

                                    sr += srcPtr2->R * srcPtr2->A;
                                    sg += srcPtr2->G * srcPtr2->A;
                                    sb += srcPtr2->B * srcPtr2->A;
                                    sa += srcPtr2->A;
                                    ++sc;
                                }
                            }

                            if (sa != 0)
                            {
                                *dstPtr = ColorBgra.FromBgra(
                                    PixelUtils.ClampToByte(sb / sa),
                                    PixelUtils.ClampToByte(sg / sa),
                                    PixelUtils.ClampToByte(sr / sa),
                                    PixelUtils.ClampToByte(sa / sc));
                            }
                            else
                            {
                                dstPtr->Bgra = 0;
                            }

                            ++srcPtr;
                            ++dstPtr;
                        }
                    }
                }
            }
        }
コード例 #29
0
ファイル: TwistEffect.cs プロジェクト: p07r0457/Pinta
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            float twist = Data.Amount;

            float hw     = dst.Width / 2.0f;
            float hh     = dst.Height / 2.0f;
            float maxrad = Math.Min(hw, hh);

            twist = twist * twist * Math.Sign(twist);

            int     aaLevel   = Data.Antialias;
            int     aaSamples = aaLevel * aaLevel + 1;
            PointD *aaPoints  = stackalloc PointD[aaSamples];

            for (int i = 0; i < aaSamples; ++i)
            {
                PointD pt = new PointD(
                    ((i * aaLevel) / (float)aaSamples),
                    i / (float)aaSamples);

                pt.X       -= (int)pt.X;
                aaPoints[i] = pt;
            }

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

            foreach (var rect in rois)
            {
                for (int y = rect.Top; y < rect.Bottom; y++)
                {
                    float      j      = y - hh;
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
                    ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_data_ptr, src_width, rect.Left, y);

                    for (int x = rect.Left; x < rect.Right; x++)
                    {
                        float i = x - hw;

                        if (i * i + j * j > (maxrad + 1) * (maxrad + 1))
                        {
                            *dstPtr = *srcPtr;
                        }
                        else
                        {
                            int b = 0;
                            int g = 0;
                            int r = 0;
                            int a = 0;

                            for (int p = 0; p < aaSamples; ++p)
                            {
                                float  u     = i + (float)aaPoints[p].X;
                                float  v     = j + (float)aaPoints[p].Y;
                                double rad   = Math.Sqrt(u * u + v * v);
                                double theta = Math.Atan2(v, u);

                                double t = 1 - rad / maxrad;

                                t = (t < 0) ? 0 : (t * t * t);

                                theta += (t * twist) / 100;

                                ColorBgra sample = src.GetPointUnchecked(src_data_ptr, src_width,
                                                                         (int)(hw + (float)(rad * Math.Cos(theta))),
                                                                         (int)(hh + (float)(rad * Math.Sin(theta))));

                                b += sample.B;
                                g += sample.G;
                                r += sample.R;
                                a += sample.A;
                            }

                            *dstPtr = ColorBgra.FromBgra(
                                (byte)(b / aaSamples),
                                (byte)(g / aaSamples),
                                (byte)(r / aaSamples),
                                (byte)(a / aaSamples));
                        }

                        ++dstPtr;
                        ++srcPtr;
                    }
                }
            }
        }
コード例 #30
0
        protected unsafe override void RenderLine(ISurface src, ISurface dest, Rectangle roi)
        {
            // Glow backgound
            glow_effect.Render(src, dest, roi);

            // Create black outlines by finding the edges of objects
            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;

                    for (int v = top; v < bottom; v++)
                    {
                        ColorBgra *pRow = src.GetRowAddress(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.desaturate_op.Apply(topLayer);

                    // Adjust Brightness and Contrast
                    if (topLayer.R > (ink_outline * 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.darken_op.Apply(topLayer, *dstPtr);
                    *         dstPtr  = myPixel;

                    ++srcPtr;
                    ++dstPtr;
                }
            }
        }