[]
        
(Showing Draft Content)

Interpolation Mode

Sometimes, you might want to draw an image using nearest-neighbor interpolation mode without resizing the image. The interpolation mode influences the way images stretch and shrink. The interpolation modes try to attain the best estimation of the intensity of a pixel based on neighboring pixel values on a proximity basis. To stretch an image, each pixel in the original image must be mapped to a group of pixels in the larger image. However, to shrink an image, groups of pixels in the original image must be mapped to single pixels in the smaller image. DsImaging supports interpolation modes to allow you to control interpolation mode in a common way for all implementations of GcGraphics class.

The GcGraphics class provides InterpolationMode property and IsInterpolationModeSupported method, which are used to control interpolation mode in a common way for all graphics. The InterpolationMode enumeration defines following interpolation modes:

  • NearestNeighbor

  • Linear

  • Cubic

  • Downscale

Original Image

NearestNeighbor

Linear

Original small image.

Image interpolated using nearest neighbor mode.

Image interpolated using linear mode.

Cubic

Downscale

Image interpolated using cubic mode.

Image interpolated using downscale mode.

The following table lists the interpolation modes supported by different GcGraphics implementations.

GcGraphics Implementations

NearestNeighbor

Linear

Cubic

Downscale

GcPdfGraphics

Yes

No

No

No

GcBitmapGraphics

Yes

Yes

Yes

Yes

GcSvgGraphics

Yes

Yes

Yes

No

GcSkiaGraphics

Yes

Yes

Yes

No

GcWicBitmapGraphics

Yes

Yes

No

No

GcD2DBitmapGraphics

Yes

Yes

No

No

The following are the usage examples of the InterpolationMode enumeration in different GcGraphics implementations:

  • The current value of the InterpolationMode property in GcGraphics class affects the way bitmap images are drawn by the DrawImage method in GcGraphics class.

  • The current value of the InterpolationMode property in BitmapRenderer class affects the way bitmap images are drawn by the DrawBitmap method in BitmapRenderer class.

  • The Resize method of GcBitmap class accepts InterpolationMode as a parameter, which affects the resulting GcBitmap image.

Refer to the following example code to enlarge a small image using different interpolation modes:

public class EnlargeQRCode
{
    public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
    {
        // Create and clear the target bitmap.
        var targetBmp = new GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi);
        targetBmp.Clear(Color.Transparent);

        const int fontSize = 16;
        var xpad = (int)(dpi * .5f);
        var ypad = (int)(dpi * .7f);

        // Initialize Font.
        TextFormat tf = new TextFormat
        {
            Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
            FontSize = fontSize,
        };

        // Load the image.
        using var origBmp = new GcBitmap();
        using (var stm = File.OpenRead(Path.Combine("Resources", "ImagesBis", "QRCode-57x57.png")))
            origBmp.Load(stm);

        // Match the opaqueness of the original bitmap and the target.
        origBmp.Opaque = targetBmp.Opaque;

        var ip = new Point(xpad, ypad);

        // Draw the original image at its original size.
        targetBmp.BitBlt(origBmp, ip.X, ip.Y);
        using (var g = targetBmp.CreateGraphics(null))
            g.DrawString($"⟵ Original image ({origBmp.PixelWidth} by {origBmp.PixelHeight} pixels)", tf, new PointF(xpad * 2 + origBmp.Width, ip.Y));
        ip.Y += origBmp.PixelHeight + ypad;

        // Enlarge the original small image by a factor of 6.
        var f = 6;
        int twidth = origBmp.PixelWidth * f;
        int theight = origBmp.PixelHeight * f;

        // Enlarge and draw four copies of the image using the four different available interpolation modes.
        using (var bmp = origBmp.Resize(twidth, theight, InterpolationMode.NearestNeighbor))
            targetBmp.BitBlt(bmp, ip.X, ip.Y);
        drawCaption("InterpolationMode.NearestNeighbor", ip.X, ip.Y + theight);

        using (var bmp = origBmp.Resize(twidth, theight, InterpolationMode.Cubic))
            targetBmp.BitBlt(bmp, ip.X + twidth + xpad, ip.Y);
        drawCaption("InterpolationMode.Cubic", ip.X + twidth + xpad, ip.Y + theight);

        ip.Y += theight + ypad;

        using (var bmp = origBmp.Resize(twidth, theight, InterpolationMode.Linear))
            targetBmp.BitBlt(bmp, ip.X, ip.Y);
        drawCaption("InterpolationMode.Linear", ip.X, ip.Y + theight);

        using (var bmp = origBmp.Resize(twidth, theight, InterpolationMode.Downscale))
            targetBmp.BitBlt(bmp, ip.X + twidth + xpad, ip.Y);
        drawCaption("InterpolationMode.Downscale", ip.X + twidth + xpad, ip.Y + theight);
        
        void drawCaption(string caption, float x, float y)
        {
            using var g = targetBmp.CreateGraphics(null);
            g.DrawString(caption, tf, new PointF(x, y));
        }
        return targetBmp;
    }
}

!type=note

Note:

The interpolation mode only affects the way raster images are drawn on a graphic, i.e., the result of DrawImage method and raster image resizing. Interpolation mode does not affect any other graphics operations. In particular, if a PDF is saved to an image format, the only items affected by interpolation mode would be raster images embedded in the original PDF, if they exist.

When a raster image is drawn on an SVG graphic (a vector graphic), the original raster image is not modified; instead, the specified interpolation mode is saved in the SVG markup as a hint to viewers on how to show the image, so it is not directly affected by the interpolation mode. The hint may be ignored, depending on the viewer. Graphics on a PDF are also vector graphics, but these graphics only support NearestNeighbor mode of InterpolationMode, meaning that raster images embedded in a PDF are always shown by PDF viewers using that mode.