Exemplo n.º 1
0
        /// <summary>
        /// </summary>
        protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken token, RenderArgs dstArgs, RenderArgs srcArgs)
        {
            //
            // This is an expensive operation, so pull the effect configuration once here rather than each time its needed during
            // effect rendering
            //
            _effectConfiguration = ShadowEffectConfiguration.FromToken(token);

            base.OnSetRenderInfo(token, dstArgs, srcArgs);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates the shadow of the source image
        /// </summary>
        /// <param name="dst">Describes the destination surface.</param>
        /// <param name="src">Describes the source surface.</param>
        /// <param name="rect">The rectangle that describes the region of interest.</param>
        /// <param name="configuration"></param>
        ///
        private unsafe void RenderRectangle(Surface dst, Surface src, Rectangle rect, ShadowEffectConfiguration configuration)
        {
            double shadowFactor = configuration.Opacity / ShadowEffectProperties.MaxOpacity;

            //
            // The blurring algorithm was stolen directly from the BlurEffect code.  I couldn't
            // use it directly because the source image must be transformed prior to applying
            // the blur effect. Also, I gradually increase the blur radius from one end
            // of the shadow to the other, which the blur effect code doesn't support either.
            //
            if (rect.Height >= 1 && rect.Width >= 1)
            {
                // For each row in the rectangle
                for (int y = rect.Top; y < rect.Bottom; ++y)
                {
                    //
                    // Shadow Diffusion - The blur radius increases the further the row is from the bottom
                    // Diffusion Factor - [0-100] How much the shadow is diffused.  0 = None, 100 = Max
                    //
                    double blurRadius = 0;
                    if (configuration.DiffusionFactor > 0)
                    {
                        // diffusion factor of 50 = 5 rows/blur_radius
                        double rowsPerBlurRadius = 250.0 / (double)configuration.DiffusionFactor;
                        blurRadius = invertedYcoordinate(y, src.Height) / rowsPerBlurRadius;
                    }

                    int[]      w      = CreateGaussianBlurRow(blurRadius);
                    int        wlen   = w.Length;
                    int        r      = (wlen - 1) / 2;
                    long[]     waSums = new long[wlen];
                    long[]     aSums  = new long[wlen];
                    long       waSum  = 0;
                    long       aSum   = 0;
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                    // For each item in the gaussian blur row
                    for (int wx = 0; wx < wlen; ++wx)
                    {
                        int srcX = rect.Left + wx - r;
                        waSums[wx] = 0;
                        aSums[wx]  = 0;

                        if (srcX >= 0 && srcX < src.Width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < src.Height)
                                {
                                    ColorBgra c  = getShadowPixel(srcX, srcY, src, shadowFactor, configuration.Angle, configuration.DepthAngle);
                                    int       wp = w[wy];

                                    waSums[wx] += wp;
                                    aSums[wx]  += wp * c.A;
                                }
                            }

                            int wwx = w[wx];
                            waSum += wwx * waSums[wx];
                            aSum  += wwx * aSums[wx];
                        }
                    }

                    if (waSum == 0)
                    {
                        dstPtr->Bgra = 0;
                    }
                    else
                    {
                        dstPtr->Bgra = ColorBgra.BgraToUInt32(0, 0, 0, (int)(aSum / waSum));
                    }

                    ++dstPtr;

                    for (int x = rect.Left + 1; x < rect.Right; ++x)
                    {
                        ColorBgra OrginalImage = src[x, y];

                        for (int i = 0; i < wlen - 1; ++i)
                        {
                            waSums[i] = waSums[i + 1];
                            aSums[i]  = aSums[i + 1];
                        }

                        waSum = 0;
                        aSum  = 0;

                        int wx;
                        for (wx = 0; wx < wlen - 1; ++wx)
                        {
                            long wwx = (long)w[wx];
                            waSum += wwx * waSums[wx];
                            aSum  += wwx * aSums[wx];
                        }

                        wx = wlen - 1;

                        waSums[wx] = 0;
                        aSums[wx]  = 0;

                        int srcX = x + wx - r;

                        if (srcX >= 0 && srcX < src.Width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < src.Height)
                                {
                                    ColorBgra c  = getShadowPixel(srcX, srcY, src, shadowFactor, configuration.Angle, configuration.DepthAngle);
                                    int       wp = w[wy];

                                    waSums[wx] += wp;
                                    aSums[wx]  += wp * (long)c.A;
                                }
                            }

                            int wr = w[wx];
                            waSum += (long)wr * waSums[wx];
                            aSum  += (long)wr * aSums[wx];
                        }

                        ColorBgra Shadow = new ColorBgra();
                        if (waSum == 0)
                        {
                            Shadow = ColorBgra.FromBgra(0, 0, 0, 0);
                        }
                        else
                        {
                            Shadow = ColorBgra.FromBgra(0, 0, 0, (byte)(aSum / waSum));
                        }

                        if (configuration.KeepOriginalImage)
                        {
                            dstPtr->Bgra = (uint)_normalOp.Apply(Shadow, OrginalImage);
                        }
                        else
                        {
                            dstPtr->Bgra = (uint)Shadow;
                        }

                        ++dstPtr;
                    }
                }
            }
        }