AForge.Imaging.Filters.TransformFromPolar.ProcessFilter C# (CSharp) Метод

ProcessFilter() защищенный Метод

Process the filter on the specified image.
protected ProcessFilter ( UnmanagedImage sourceData, UnmanagedImage destinationData ) : void
sourceData UnmanagedImage Source image data.
destinationData UnmanagedImage Destination image data.
Результат void
        protected override unsafe void ProcessFilter( UnmanagedImage sourceData, UnmanagedImage destinationData )
        {
            int pixelSize = Bitmap.GetPixelFormatSize( destinationData.PixelFormat ) / 8;

            // get source image size
            int width  = sourceData.Width;
            int height = sourceData.Height;
            int widthM1  = width - 1;
            int heightM1 = height - 1;

            // get destination image size
            int newWidth  = destinationData.Width;
            int newHeight = destinationData.Height;
            int newWidthM1  = newWidth - 1;
            int newHeightM1 = newHeight - 1;

            // invert cirlce depth
            double circleDisform = 1 - circleDepth;

            // get position of center pixel
            double cx = (double) widthM1 / 2;
            double cy = (double) heightM1 / 2;
            double radius = ( cx < cy ) ? cx : cy;
            radius -= radius * circleDisform;

            // angle of the diagonal
            double diagonalAngle = Math.Atan2( cy, cx );

            // offset angle in radians
            double offsetAngleR = ( ( mapBackwards ) ? offsetAngle : -offsetAngle ) / 180 * Math.PI + PiHalf;

            // do the job
            byte* baseSrc = (byte*) sourceData.ImageData.ToPointer( );
            byte* dst = (byte*) destinationData.ImageData.ToPointer( );

            int srcStride = sourceData.Stride;
            int dstOffset = destinationData.Stride - newWidth * pixelSize;

            // coordinates of source points
            int sx1, sy1, sx2, sy2;
            double dx1, dy1, dx2, dy2;

            // temporary pointers
            byte* p1, p2, p3, p4;

            // precalculate Sin/Cos values and distances from center to edge in the source image
            double[] angleCos = new double[newWidth];
            double[] angleSin = new double[newWidth];
            double[] maxDistance = new double[newWidth];

            for ( int x = 0; x < newWidth; x++ )
            {
                double angle = -Pi2 * x / newWidth + offsetAngleR;

                angleCos[x] = Math.Cos( angle );
                angleSin[x] = Math.Sin( angle );

                // calculate minimum angle between X axis and the
                // line with the above calculated angle
                double oxAngle = ( ( angle > 0 ) ? angle : -angle ) % Math.PI;
                if ( oxAngle > PiHalf )
                {
                    oxAngle = Math.PI - oxAngle;
                }

                // calculate maximm distance from center for this angle - distance to image's edge
                maxDistance[x] = circleDisform * ( ( oxAngle > diagonalAngle ) ? ( cy / Math.Sin( oxAngle ) ) : ( cx / Math.Cos( oxAngle ) ) );
            }

            for ( int y = 0; y < newHeight; y++ )
            {
                double yPart = (double) y / newHeightM1;

                if ( !mapFromTop )
                {
                    yPart = 1 - yPart;
                }

                for ( int x = 0; x < newWidth; x++ )
                {
                    // calculate maximum allowed distance within wich we need to map Y axis of the destination image
                    double maxAllowedDistance = radius + maxDistance[x];

                    // source pixel's distance from the center of the source image
                    double distance = yPart * maxAllowedDistance;

                    // calculate pixel coordinates in the source image
                    double sx = cx + distance * ( ( mapBackwards ) ? -angleCos[x] : angleCos[x] );
                    double sy = cy - distance * angleSin[x];

                    sx1 = (int) sx;
                    sy1 = (int) sy;

                    sx2 = ( sx1 == widthM1 ) ? sx1 : sx1 + 1;
                    dx1 = sx - sx1;
                    dx2 = 1.0 - dx1;

                    sy2 = ( sy1 == heightM1 ) ? sy1 : sy1 + 1;
                    dy1 = sy - sy1;
                    dy2 = 1.0 - dy1;

                    // get four points
                    p1 = p2 = baseSrc + sy1 * srcStride;
                    p1 += sx1 * pixelSize;
                    p2 += sx2 * pixelSize;

                    p3 = p4 = baseSrc + sy2 * srcStride;
                    p3 += sx1 * pixelSize;
                    p4 += sx2 * pixelSize;

                    // interpolate using 4 points
                    for ( int i = 0; i < pixelSize; i++, dst++, p1++, p2++, p3++, p4++ )
                    {
                        *dst = (byte) (
                            dy2 * ( dx2 * ( *p1 ) + dx1 * ( *p2 ) ) +
                            dy1 * ( dx2 * ( *p3 ) + dx1 * ( *p4 ) ) );
                    }
                }
                dst += dstOffset;
            }
        }
    }