Ever wish the picture box could scale images without using bilinear filtering (for example, when viewing/editing video game graphics)? In the past I had written controls from scratch that emulate the PictureBox but used my desired interpolation. Then I was hit with a stroke of common sense. I've extended the PictureBox class to enhance it with the ability to use various interpolation modes, including the video game creator's best friend, nearest neighbor.
Since I'm such a swell guy, I translated it to VB too.
C#:
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System;
namespace iLab
{
/// <summary>
/// A PictureBox control extended to allow a variety of interpolations.
/// </summary>
class InterpolatedBox:pictureBox
{
#region Interpolation Property
/// <summary>Backing Field</summary>
private InterpolationMode interpolation = InterpolationMode.Default;
/// <summary>
/// The interpolation used to render the image.
/// </summary>
[DefaultValue(typeof(InterpolationMode), "Default"),
Description("The interpolation used to render the image.")]
public InterpolationMode Interpolation {
get { return interpolation; }
set {
if(value == InterpolationMode.Invalid)
throw new ArgumentException("\"Invalid\" is not a valid value."); // (Duh!)
interpolation = value;
Invalidate(); // Image should be redrawn when a different interpolation is selected
}
}
#endregion
/// <summary>
/// Overridden to modify rendering behavior.
/// </summary>
/// <param name="pe">Painting event args.</param>
protected override void OnPaint(PaintEventArgs pe) {
// Before the PictureBox renders the image, we modify the
// graphics object to change the interpolation.
// Set the selected interpolation.
pe.Graphics.InterpolationMode = interpolation;
// Certain interpolation modes (such as nearest neighbor) need
// to be offset by half a pixel to render correctly.
pe.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
// Allow the PictureBox to draw.
base.OnPaint(pe);
}
}
}
Visual Basic:
Imports System.Drawing.Drawing2D
Imports System.ComponentModel
''' <summary>A PictureBox control extended to allow a variety of interpolations.</summary>
Public Class InterpolatedBox
Inherits PictureBox
''' <summary>The backing field for the Interpolation property</summary>
Dim _interpolation As InterpolationMode = InterpolationMode.Default
''' <summary>
''' The interpolation used to render the image.
''' </summary>
<DefaultValue(GetType(InterpolationMode), "Default"), _
Description("The interpolation used to render the image.")> _
Public Property Interpolation() As InterpolationMode
Get
Return _interpolation
End Get
Set(ByVal value As InterpolationMode)
If value = InterpolationMode.Invalid Then _
Throw New ArgumentException("""Invalid"" is not a valid value.") '(duh.)
_interpolation = value
Invalidate() 'Image should be redrawn when a different interpolation is selected
End Set
End Property
''' <summary>
''' Overridden to modify rendering behavior.
''' </summary>
''' <param name="pe">Painting event args.</param>
Protected Overrides Sub OnPaint(ByVal pe As System.Windows.Forms.PaintEventArgs)
' Before the PictureBox renders the image, we modify the
' graphics object to change the interpolation.
' Set the selected interpolation.
pe.Graphics.InterpolationMode = _interpolation
' Certain interpolation modes (such as nearest neighbor) need
' to be offset by half a pixel to render correctly.
pe.Graphics.PixelOffsetMode = PixelOffsetMode.Half
' Allow the PictureBox to draw.
MyBase.OnPaint(pe)
End Sub
End Class
Last edited by a moderator: