コード例 #1
0
    public Bitmap Resample(Bitmap image, int width, int height)
    {
        ResamplingService resamplingService = new ResamplingService();

        resamplingService.Filter = ResamplingFilters.Lanczos3;
        ushort[][,] input        = ResamplingFilter.ConvertBitmapToArray((Bitmap)image);
        ushort[][,] output       = resamplingService.Resample(input, width, height);
        Bitmap result = (Bitmap)ResamplingFilter.ConvertArrayToBitmap(output);

        return(result);
    }
コード例 #2
0
    public void Resample(ResamplingFilters filter, int newWidth, int newHeight)
    {
        if (Disposed)
        {
            return;
        }
        ResamplingService resamplingService = new ResamplingService();

        resamplingService.Filter = filter;
        var array  = ResamplingFilter.ConvertByteArrayToArray((byte *)this.Bytes.ToPointer(), this.Width, this.Height);
        var result = resamplingService.Resample(array, newWidth, newHeight);

        this.InternalResize(newWidth, newHeight);
        ResamplingFilter.ConvertArrayToByteArray(result, (byte *)this.Bytes.ToPointer());
    }
コード例 #3
0
    /// <summary>
    /// Resamples input array to a new array using current resampling filter.
    /// </summary>
    /// <param name="input">Input array.</param>
    /// <param name="nWidth">Width of the output array.</param>
    /// <param name="nHeight">Height of the output array.</param>
    /// <returns>Output array.</returns>
    public ushort[][,] Resample(ushort[][,] input, int nWidth, int nHeight)
    {
        if (input == null || input.Length == 0 || nWidth < 1 || nHeight < 1)
        {
            return(null);
        }

        ResamplingFilter filter = ResamplingFilter.Create(this.filter);

        int width  = input[0].GetLength(0);
        int height = input[0].GetLength(1);
        int planes = input.Length;

        this.covered = 0;
        this.total   = (nWidth + height);

        // create bitmaps
        ushort[][,] work   = new ushort[planes][, ];
        ushort[][,] output = new ushort[planes][, ];
        int c = 0;

        for (c = 0; c < planes; c++)
        {
            work[c]   = new ushort[nWidth, height];
            output[c] = new ushort[nWidth, nHeight];
        }

        double xScale = ((double)nWidth / width);
        double yScale = ((double)nHeight / height);

        ContributorEntry[] contrib = new ContributorEntry[nWidth];

        double wdth = 0, center = 0, weight = 0, intensity = 0;
        int    left = 0, right = 0, i = 0, j = 0, k = 0;

        // horizontal downsampling
        if (xScale < 1.0)
        {
            // scales from bigger to smaller width
            wdth = (filter.defaultFilterRadius / xScale);

            for (i = 0; i < nWidth; i++)
            {
                contrib[i].n    = 0;
                contrib[i].p    = new Contributor[(int)Math.Floor(2 * wdth + 1)];
                contrib[i].wsum = 0;
                center          = ((i + 0.5) / xScale);
                left            = (int)(center - wdth);
                right           = (int)(center + wdth);

                for (j = left; j <= right; j++)
                {
                    weight = filter.GetValue((center - j - 0.5) * xScale);

                    if ((weight == 0) || (j < 0) || (j >= width))
                    {
                        continue;
                    }

                    contrib[i].p[contrib[i].n].pixel  = j;
                    contrib[i].p[contrib[i].n].weight = weight;
                    contrib[i].wsum += weight;
                    contrib[i].n++;
                }

                if (aborting)
                {
                    goto End;
                }
            }
        }
        else
        {
            // horizontal upsampling
            // scales from smaller to bigger width
            for (i = 0; i < nWidth; i++)
            {
                contrib[i].n    = 0;
                contrib[i].p    = new Contributor[(int)Math.Floor(2 * filter.defaultFilterRadius + 1)];
                contrib[i].wsum = 0;
                center          = ((i + 0.5) / xScale);
                left            = (int)Math.Floor(center - filter.defaultFilterRadius);
                right           = (int)Math.Ceiling(center + filter.defaultFilterRadius);

                for (j = left; j <= right; j++)
                {
                    weight = filter.GetValue(center - j - 0.5);

                    if ((weight == 0) || (j < 0) || (j >= width))
                    {
                        continue;
                    }

                    contrib[i].p[contrib[i].n].pixel  = j;
                    contrib[i].p[contrib[i].n].weight = weight;
                    contrib[i].wsum += weight;
                    contrib[i].n++;
                }

                if (aborting)
                {
                    goto End;
                }
            }
        }

        // filter horizontally from input to work
        for (c = 0; c < planes; c++)
        {
            for (k = 0; k < height; k++)
            {
                for (i = 0; i < nWidth; i++)
                {
                    intensity = 0;

                    for (j = 0; j < contrib[i].n; j++)
                    {
                        weight = contrib[i].p[j].weight;

                        if (weight == 0)
                        {
                            continue;
                        }

                        intensity += (input[c][contrib[i].p[j].pixel, k] * weight);
                    }

                    work[c][i, k] = (ushort)Math.Min(Math.Max(intensity / contrib[i].wsum + 0.5, UInt16.MinValue), UInt16.MaxValue);
                }

                if (aborting)
                {
                    goto End;
                }

                this.covered++;
            }
        }

        // pre-calculate filter contributions for a column
        contrib = new ContributorEntry[nHeight];

        // vertical downsampling
        if (yScale < 1.0)
        {
            // scales from bigger to smaller height
            wdth = (filter.defaultFilterRadius / yScale);

            for (i = 0; i < nHeight; i++)
            {
                contrib[i].n    = 0;
                contrib[i].p    = new Contributor[(int)Math.Floor(2 * wdth + 1)];
                contrib[i].wsum = 0;
                center          = ((i + 0.5) / yScale);
                left            = (int)(center - wdth);
                right           = (int)(center + wdth);

                for (j = left; j <= right; j++)
                {
                    weight = filter.GetValue((center - j - 0.5) * yScale);

                    if ((weight == 0) || (j < 0) || (j >= height))
                    {
                        continue;
                    }

                    contrib[i].p[contrib[i].n].pixel  = j;
                    contrib[i].p[contrib[i].n].weight = weight;
                    contrib[i].wsum += weight;
                    contrib[i].n++;
                }

                if (aborting)
                {
                    goto End;
                }
            }
        }
        else
        {
            // vertical upsampling
            // scales from smaller to bigger height
            for (i = 0; i < nHeight; i++)
            {
                contrib[i].n    = 0;
                contrib[i].p    = new Contributor[(int)Math.Floor(2 * filter.defaultFilterRadius + 1)];
                contrib[i].wsum = 0;
                center          = ((i + 0.5) / yScale);
                left            = (int)(center - filter.defaultFilterRadius);
                right           = (int)(center + filter.defaultFilterRadius);

                for (j = left; j <= right; j++)
                {
                    weight = filter.GetValue(center - j - 0.5);

                    if ((weight == 0) || (j < 0) || (j >= height))
                    {
                        continue;
                    }

                    contrib[i].p[contrib[i].n].pixel  = j;
                    contrib[i].p[contrib[i].n].weight = weight;
                    contrib[i].wsum += weight;
                    contrib[i].n++;
                }

                if (aborting)
                {
                    goto End;
                }
            }
        }

        // filter vertically from work to output
        for (c = 0; c < planes; c++)
        {
            for (k = 0; k < nWidth; k++)
            {
                for (i = 0; i < nHeight; i++)
                {
                    intensity = 0;

                    for (j = 0; j < contrib[i].n; j++)
                    {
                        weight = contrib[i].p[j].weight;

                        if (weight == 0)
                        {
                            continue;
                        }

                        intensity += (work[c][k, contrib[i].p[j].pixel] * weight);
                    }

                    output[c][k, i] = (ushort)Math.Min(Math.Max(intensity / contrib[i].wsum + 0.5, UInt16.MinValue), UInt16.MaxValue);
                }

                if (aborting)
                {
                    goto End;
                }

                this.covered++;
            }
        }

        End :;

        work = null;

        return(output);
    }
コード例 #4
0
    public static ResamplingFilter Create(ResamplingFilters filter)
    {
        ResamplingFilter resamplingFilter = null;

        switch (filter)
        {
        case ResamplingFilters.Box:
            resamplingFilter = new BoxFilter();
            break;

        case ResamplingFilters.Triangle:
            resamplingFilter = new TriangleFilter();
            break;

        case ResamplingFilters.Hermite:
            resamplingFilter = new HermiteFilter();
            break;

        case ResamplingFilters.Bell:
            resamplingFilter = new BellFilter();
            break;

        case ResamplingFilters.CubicBSpline:
            resamplingFilter = new CubicBSplineFilter();
            break;

        case ResamplingFilters.Lanczos3:
            resamplingFilter = new Lanczos3Filter();
            break;

        case ResamplingFilters.Mitchell:
            resamplingFilter = new MitchellFilter();
            break;

        case ResamplingFilters.Cosine:
            resamplingFilter = new CosineFilter();
            break;

        case ResamplingFilters.CatmullRom:
            resamplingFilter = new CatmullRomFilter();
            break;

        case ResamplingFilters.Quadratic:
            resamplingFilter = new QuadraticFilter();
            break;

        case ResamplingFilters.QuadraticBSpline:
            resamplingFilter = new QuadraticBSplineFilter();
            break;

        case ResamplingFilters.CubicConvolution:
            resamplingFilter = new CubicConvolutionFilter();
            break;

        case ResamplingFilters.Lanczos8:
            resamplingFilter = new Lanczos8Filter();
            break;
        }

        return(resamplingFilter);
    }