예제 #1
0
        /// <summary>
        /// Fits the source surface to this surface using bilinear interpolation.
        /// </summary>
        /// <param name="source">The surface to read pixels from.</param>
        /// <param name="dstRoi">The rectangle to clip rendering to.</param>
        /// <remarks>This method was implemented with correctness, not performance, in mind.</remarks>
        public void BilinearFitSurface(Surface source, Rectangle dstRoi)
        {
            if (dstRoi.Width < 2 || dstRoi.Height < 2 || this.width < 2 || this.height < 2)
            {
                SuperSamplingFitSurface(source, dstRoi);
            }
            else
            {
                unsafe
                {
                    Rectangle roi = Rectangle.Intersect(dstRoi, this.Bounds);

                    for (int dstY = roi.Top; dstY < roi.Bottom; ++dstY)
                    {
                        ColorBgra *dstRowPtr = this.GetRowAddressUnchecked(dstY);
                        float srcRow = (float)(dstY * (source.height - 1)) / (float)(height - 1);

                        for (int dstX = roi.Left; dstX < roi.Right; dstX++)
                        {
                            float srcColumn = (float)(dstX * (source.width - 1)) / (float)(width - 1);
                            *dstRowPtr = source.GetBilinearSample(srcColumn, srcRow);
                            ++dstRowPtr;
                        }
                    }
                }
            }
        }
예제 #2
0
        void Render(Surface dst, Surface src, Rectangle rect)
        {
            Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
            long CenterX = (long)((1.0 + Amount3.First) * ((selection.Right - selection.Left) / 2) + selection.Left);
            long CenterY = (long)((1.0 + Amount3.Second) * ((selection.Bottom - selection.Top) / 2) + selection.Top);

            double rfrac = Math.Log(Amount2 / Amount1);
            double alpha = Math.Atan2(rfrac, Math.PI * 2);
            double f = Math.Cos(alpha);
            Complex ialpha = Complex.FromRealImaginary(0, alpha);
            Complex beta = f * ialpha.Exponential();

            Complex zin;
            Complex ztemp1;
            Complex ztemp2;
            Complex zout;

            float from_x;
            float from_y;

            float rotatedX;
            float rotatedY;
            double angle = Amount6 * Math.PI / 180.0;
            double cos = Math.Cos(angle);
            double sin = Math.Sin(angle);

            ColorBgra result;

            for (int y = rect.Top; y < rect.Bottom; ++y)
            {
                if (IsCancelRequested) return;
                for (int x = rect.Left; x < rect.Right; ++x)
                {
                    zout = Complex.FromRealImaginary(x - CenterX, CenterY - y);
                    result = ColorBgra.Zero;

                    // see algorithm description here : http://www.josleys.com/articles/printgallery.htm

                    // inverse step 3 and inverse step 2 ==> output after step 1
                    ztemp1 = MyNaturalLogarithm(zout) / beta;

                    for (int layer = 0; layer < 3 && result.A < 255; layer++)
                    {
                        // convert to a point with real part inside [0 , log (r1/r2)]
                        // combine with data in [log (r1/r2), 2 * log (r1/r2)] if not opaque
                        // maybe even go to the part after that etc...
                        double rtemp = 0;
                        if (Amount4)
                        {
                            rtemp = ztemp1.Real % rfrac + (2 - layer) * rfrac;
                        }
                        else
                        {
                            rtemp = ztemp1.Real % rfrac + layer * rfrac;
                        }

                        ztemp2 = Complex.FromRealImaginary(rtemp, ztemp1.Imag * Amount5);

                        // inverse step 1
                        zin = Amount1 * ztemp2.Exponential();

                        from_x = (float)(zin.Real + CenterX);
                        from_y = (float)(CenterY - zin.Imag);

                        rotatedX = (float)((from_x - CenterX) * cos - (from_y - CenterY) * sin + CenterX);
                        rotatedY = (float)((from_y - CenterY) * cos - (from_x - CenterX) * -1.0 * sin + CenterY);

                        result = AddColor(result, src.GetBilinearSample(rotatedX, rotatedY));
                    }
                    dst[x, y] = result;
                }
            }
        }