Ejemplo n.º 1
0
        /// <summary>
        /// Performs a scaled linear re-projection into the specified target block.
        /// <br/>
        /// Uses the given mapping function only to determine the corresponding corner points in the source image,
        /// uses a linear interpolation to determine intermediate points.
        /// </summary>
        /// <param name="source">The image to be re-projected.</param>
        /// <param name="target">The resulting image to be filled.</param>
        /// <param name="block">The block being targeted.</param>
        /// <param name="transformTargetToSource">Mapping function that maps target to source pixels.</param>
        /// <param name="scale">A factor to apply when re-projecting the block. See code comments in Reproject method above, where this parameter is set up.</param>
        private static void ScaledReprojection(ArgbImage source, ArgbImage target, ReprojectionBlock block, Func <PointD, PointD> transformTargetToSource, Size scale)
        {
            // determine the number of sections of the scaled block
            var nx = (block.X1 - block.X0 + 1) * scale.Width - 1;
            var ny = (block.Y1 - block.Y0 + 1) * scale.Height - 1;

            // Interpolators for upper and lower line of block
            var upper = InterpolationData.Create(transformTargetToSource(block.LeftTop), transformTargetToSource(block.RightTop), nx);
            var lower = InterpolationData.Create(transformTargetToSource(block.LeftBottom), transformTargetToSource(block.RightBottom), nx);

            // total number of color components collected in a color block due to scaling
            var colorBlockSize = (uint)(scale.Width * scale.Height);

            for (var x = block.X0; x <= block.X1; ++x)
            {
                // setup scale.Width interpolators for interpolating points on the line
                // defined through upper+n and lower+n, with n=0..(scale.Width-1)

                var sourcePoint = new InterpolationData[scale.Width];

                for (var xsub = 0; xsub < scale.Width; ++xsub)
                {
                    sourcePoint[xsub] = InterpolationData.Create(upper++, lower++, ny);
                }

                for (var y = block.Y0; y <= block.Y1; ++y)
                {
                    // storage for color components
                    uint a, r, g, b;
                    a = r = g = b = colorBlockSize >> 2;

                    // collect color components of subpixels.
                    // In the inner loop, we'll step our sourcePoint interpolators.
                    for (var ysub = 0; ysub < scale.Height; ++ysub)
                    {
                        for (var xsub = 0; xsub < scale.Width; ++sourcePoint[xsub], ++xsub)
                        {
                            var color = source[sourcePoint[xsub].x, sourcePoint[xsub].y];

                            a += (color >> 24) & 0xff;
                            r += (color >> 16) & 0xff;
                            g += (color >> 8) & 0xff;
                            b += color & 0xff;
                        }
                    }

                    // average the collected color components and set the target pixel
                    target[x, y] =
                        ((a / colorBlockSize) << 24) |
                        ((r / colorBlockSize) << 16) |
                        ((g / colorBlockSize) << 8) |
                        (b / colorBlockSize);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Performs a scaled linear re-projection into the specified target block.
        /// <br/>
        /// Uses the given mapping function only to determine the corresponding corner points in the source image,
        /// uses a linear interpolation to determine intermediate points.
        /// </summary>
        /// <param name="source">The image to be re-projected.</param>
        /// <param name="target">The resulting image to be filled.</param>
        /// <param name="block">The block being targeted.</param>
        /// <param name="transformTargetToSource">Mapping function that maps target to source pixels.</param>
        /// <param name="scaleY">A factor to apply when re-projecting the block. See code comments in Reproject method above, where this parameter is set up.</param>
        private static void VerticallyScaledReprojection(ArgbImage source, ArgbImage target, ReprojectionBlock block, Func <PointD, PointD> transformTargetToSource, int scaleY)
        {
            // determine the number of sections of the scaled block
            var nx = block.X1 - block.X0;
            var ny = (block.Y1 - block.Y0 + 1) * scaleY - 1;

            // Interpolators for upper and lower line of block
            var upper = InterpolationData.Create(transformTargetToSource(block.LeftTop), transformTargetToSource(block.RightTop), nx);
            var lower = InterpolationData.Create(transformTargetToSource(block.LeftBottom), transformTargetToSource(block.RightBottom), nx);

            // total number of color components collected in a color block due to scaling
            var colorBlockSize = (uint)scaleY;

            for (var x = block.X0; x <= block.X1; ++x, ++upper, ++lower)
            {
                // setup interpolator for interpolating points on the line defined through upper and lower

                var sourcePoint = InterpolationData.Create(upper, lower, ny);

                for (var y = block.Y0; y <= block.Y1; ++y)
                {
                    // storage for color components
                    uint a, r, g, b;
                    a = r = g = b = colorBlockSize >> 2;

                    // collect color components of sub pixels.
                    // In the inner loop, we'll step our sourcePoint interpolators.
                    for (var ysub = 0; ysub < scaleY; ++ysub, ++sourcePoint)
                    {
                        var color = source[sourcePoint.x, sourcePoint.y];

                        a += (color >> 24) & 0xff;
                        r += (color >> 16) & 0xff;
                        g += (color >> 8) & 0xff;
                        b += color & 0xff;
                    }

                    // average the collected color components and set the target pixel
                    target[x, y] =
                        ((a / colorBlockSize) << 24) |
                        ((r / colorBlockSize) << 16) |
                        ((g / colorBlockSize) << 8) |
                        (b / colorBlockSize);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Performs a unscaled linear re-projection into the specified target block.
        /// <br/>
        /// Uses the given mapping function only to determine the corresponding corner points in the source image,
        /// uses a linear interpolation to determine intermediate points.
        /// </summary>
        /// <param name="source">The image to be re-projected.</param>
        /// <param name="target">The resulting image to be filled.</param>
        /// <param name="block">The block being targeted.</param>
        /// <param name="transformTargetToSource">Mapping function that maps target to source pixels.</param>
        private static void UnscaledReprojection(ArgbImage source, ArgbImage target, ReprojectionBlock block, Func <PointD, PointD> transformTargetToSource)
        {
            // Interpolators for upper and lower line of block
            var upper = InterpolationData.Create(transformTargetToSource(block.LeftTop), transformTargetToSource(block.RightTop), block.X1 - block.X0);
            var lower = InterpolationData.Create(transformTargetToSource(block.LeftBottom), transformTargetToSource(block.RightBottom), block.X1 - block.X0);

            for (var x = block.X0; x <= block.X1; ++x, ++upper, ++lower)
            {
                // interpolator for points on the current line defined through upper and lower
                var sourcePoint = InterpolationData.Create(upper, lower, block.Y1 - block.Y0);

                for (var y = block.Y0; y <= block.Y1; ++y, ++sourcePoint)
                {
                    target[x, y] = source[sourcePoint.x, sourcePoint.y];
                }
            }
        }