示例#1
0
        // [Fact]
        public void PrintWeightsData()
        {
            var size = new Size(500, 500);
            var proc = new ResizeProcessor <Rgba32>(KnownResamplers.Bicubic, 200, 200, size);

            WeightsBuffer weights = proc.PrecomputeWeights(Configuration.Default.MemoryManager, proc.Width, size.Width);

            var bld = new StringBuilder();

            foreach (WeightsWindow window in weights.Weights)
            {
                Span <float> span = window.GetWindowSpan();
                for (int i = 0; i < window.Length; i++)
                {
                    float value = span[i];
                    bld.Append(value);
                    bld.Append("| ");
                }

                bld.AppendLine();
            }

            File.WriteAllText("BicubicWeights.MD", bld.ToString());

            // this.Output.WriteLine(bld.ToString());
        }
 /// <inheritdoc />
 protected override void AfterApply(ImageBase <TColor> source, Rectangle sourceRectangle)
 {
     base.AfterApply(source, sourceRectangle);
     this.HorizontalWeights?.Dispose();
     this.HorizontalWeights = null;
     this.VerticalWeights?.Dispose();
     this.VerticalWeights = null;
 }
        /// <summary>
        /// Computes the weights to apply at each pixel when resizing.
        /// </summary>
        /// <param name="destinationSize">The destination size</param>
        /// <param name="sourceSize">The source size</param>
        /// <returns>The <see cref="WeightsBuffer"/></returns>
        // TODO: Made internal to simplify experimenting with weights data. Make it protected again when finished figuring out how to optimize all the stuff!
        internal unsafe WeightsBuffer PrecomputeWeights(int destinationSize, int sourceSize)
        {
            float ratio = (float)sourceSize / destinationSize;
            float scale = ratio;

            if (scale < 1F)
            {
                scale = 1F;
            }

            IResampler    sampler = this.Sampler;
            float         radius  = MathF.Ceiling(scale * sampler.Radius);
            WeightsBuffer result  = new WeightsBuffer(sourceSize, destinationSize);

            for (int i = 0; i < destinationSize; i++)
            {
                float center = ((i + .5F) * ratio) - .5F;

                // Keep inside bounds.
                int left = (int)Math.Ceiling(center - radius);
                if (left < 0)
                {
                    left = 0;
                }

                int right = (int)Math.Floor(center + radius);
                if (right > sourceSize - 1)
                {
                    right = sourceSize - 1;
                }

                float sum = 0;

                WeightsWindow ws = result.GetWeightsWindow(i, left, right);
                result.Weights[i] = ws;

                ref float weights = ref ws.Ptr;

                for (int j = left; j <= right; j++)
                {
                    float weight = sampler.GetValue((j - center) / scale);
                    sum += weight;

                    // weights[j - left] = weight:
                    Unsafe.Add(ref weights, j - left) = weight;
                }

                // Normalise, best to do it here rather than in the pixel loop later on.
                if (sum > 0)
                {
                    for (int w = 0; w < ws.Length; w++)
                    {
                        // weights[w] = weights[w] / sum:
                        ref float wRef = ref Unsafe.Add(ref weights, w);
                        wRef = wRef / sum;
                    }
                }
        /// <inheritdoc/>
        protected override void BeforeApply(ImageBase <TColor> source, Rectangle sourceRectangle)
        {
            if (!(this.Sampler is NearestNeighborResampler))
            {
                this.HorizontalWeights = this.PrecomputeWeights(
                    this.ResizeRectangle.Width,
                    sourceRectangle.Width);

                this.VerticalWeights = this.PrecomputeWeights(
                    this.ResizeRectangle.Height,
                    sourceRectangle.Height);
            }
        }