Ejemplo n.º 1
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, ImageFrame <TPixel> destination)
        {
            Rectangle     sourceRectangle = this.SourceRectangle;
            Configuration configuration   = this.Configuration;

            // Handle resize dimensions identical to the original
            if (source.Width == destination.Width &&
                source.Height == destination.Height &&
                sourceRectangle == this.targetRectangle)
            {
                // The cloned will be blank here copy all the pixel data over
                source.GetPixelMemoryGroup().CopyTo(destination.GetPixelMemoryGroup());
                return;
            }

            int width    = this.targetWidth;
            int height   = this.targetHeight;
            var interest = Rectangle.Intersect(this.targetRectangle, new Rectangle(0, 0, width, height));

            if (this.resampler is NearestNeighborResampler)
            {
                // Scaling factors
                float widthFactor  = sourceRectangle.Width / (float)this.targetRectangle.Width;
                float heightFactor = sourceRectangle.Height / (float)this.targetRectangle.Height;

                var operation = new RowIntervalOperation(sourceRectangle, this.targetRectangle, widthFactor, heightFactor, source, destination);
                ParallelRowIterator.IterateRows(
                    configuration,
                    interest,
                    in operation);

                return;
            }

            PixelConversionModifiers conversionModifiers =
                PixelConversionModifiers.Premultiply.ApplyCompanding(this.compand);

            BufferArea <TPixel> sourceArea = source.PixelBuffer.GetArea(sourceRectangle);

            // To reintroduce parallel processing, we to launch multiple workers
            // for different row intervals of the image.
            using (var worker = new ResizeWorker <TPixel>(
                       configuration,
                       sourceArea,
                       conversionModifiers,
                       this.horizontalKernelMap,
                       this.verticalKernelMap,
                       width,
                       interest,
                       this.targetRectangle.Location))
            {
                worker.Initialize();

                var workingInterval = new RowInterval(interest.Top, interest.Bottom);
                worker.FillDestinationPixels(workingInterval, destination.PixelBuffer);
            }
        }
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, ImageFrame <TPixel> destination)
        {
            Rectangle     sourceRectangle = this.SourceRectangle;
            Configuration configuration   = this.Configuration;

            // Handle resize dimensions identical to the original
            if (source.Width == destination.Width && source.Height == destination.Height && sourceRectangle == this.targetRectangle)
            {
                // The cloned will be blank here copy all the pixel data over
                source.GetPixelSpan().CopyTo(destination.GetPixelSpan());
                return;
            }

            int width   = this.targetWidth;
            int height  = this.targetHeight;
            int sourceX = sourceRectangle.X;
            int sourceY = sourceRectangle.Y;
            int startY  = this.targetRectangle.Y;
            int startX  = this.targetRectangle.X;

            var targetWorkingRect = Rectangle.Intersect(
                this.targetRectangle,
                new Rectangle(0, 0, width, height));

            if (this.resampler is NearestNeighborResampler)
            {
                // Scaling factors
                float widthFactor  = sourceRectangle.Width / (float)this.targetRectangle.Width;
                float heightFactor = sourceRectangle.Height / (float)this.targetRectangle.Height;

                ParallelHelper.IterateRows(
                    targetWorkingRect,
                    configuration,
                    rows =>
                {
                    for (int y = rows.Min; y < rows.Max; y++)
                    {
                        // Y coordinates of source points
                        Span <TPixel> sourceRow = source.GetPixelRowSpan((int)(((y - startY) * heightFactor) + sourceY));
                        Span <TPixel> targetRow = destination.GetPixelRowSpan(y);

                        for (int x = targetWorkingRect.Left; x < targetWorkingRect.Right; x++)
                        {
                            // X coordinates of source points
                            targetRow[x] = sourceRow[(int)(((x - startX) * widthFactor) + sourceX)];
                        }
                    }
                });

                return;
            }

            PixelConversionModifiers conversionModifiers =
                PixelConversionModifiers.Premultiply.ApplyCompanding(this.compand);

            BufferArea <TPixel> sourceArea = source.PixelBuffer.GetArea(sourceRectangle);

            // To reintroduce parallel processing, we to launch multiple workers
            // for different row intervals of the image.
            using (var worker = new ResizeWorker <TPixel>(
                       configuration,
                       sourceArea,
                       conversionModifiers,
                       this.horizontalKernelMap,
                       this.verticalKernelMap,
                       width,
                       targetWorkingRect,
                       this.targetRectangle.Location))
            {
                worker.Initialize();

                var workingInterval = new RowInterval(targetWorkingRect.Top, targetWorkingRect.Bottom);
                worker.FillDestinationPixels(workingInterval, destination.PixelBuffer);
            }
        }