¿Cómo hago para que un PictureBox utilice el remuestreo del vecino más cercano?
-
09-06-2019 - |
Pregunta
Estoy usando StretchImage porque el tamaño del cuadro se puede cambiar con divisores.Parece que el valor predeterminado es algún tipo de filtrado bilineal suave, lo que hace que mi imagen se vea borrosa y tenga patrones muaré.
Solución
También necesitaba esta funcionalidad.Hice una clase que hereda PictureBox, anula OnPaint
y agrega una propiedad para permitir que se establezca el modo de interpolación:
using System.Drawing.Drawing2D;
using System.Windows.Forms;
/// <summary>
/// Inherits from PictureBox; adds Interpolation Mode Setting
/// </summary>
public class PictureBoxWithInterpolationMode : PictureBox
{
public InterpolationMode InterpolationMode { get; set; }
protected override void OnPaint(PaintEventArgs paintEventArgs)
{
paintEventArgs.Graphics.InterpolationMode = InterpolationMode;
base.OnPaint(paintEventArgs);
}
}
Otros consejos
Sospecho que tendrás que cambiar el tamaño manualmente a través de la clase Imagen y la función DrawImage y responder a los eventos de cambio de tamaño en PictureBox.
Hice una búsqueda en MSDN y resultó que hay un artículo sobre esto, que no es muy detallado pero describe que debes usar el evento paint.
http://msdn.microsoft.com/en-us/library/k0fsyd4e.aspx
Edité un ejemplo de zoom de imagen comúnmente disponible para usar esta función, ver más abajo
Editado de: http://www.dotnetcurry.com/ShowArticle.aspx?ID=196&AspxAutoDetectCookieSupport=1
Espero que esto ayude
private void Form1_Load(object sender, EventArgs e)
{
// set image location
imgOriginal = new Bitmap(Image.FromFile(@"C:\images\TestImage.bmp"));
picBox.Image = imgOriginal;
// set Picture Box Attributes
picBox.SizeMode = PictureBoxSizeMode.StretchImage;
// set Slider Attributes
zoomSlider.Minimum = 1;
zoomSlider.Maximum = 5;
zoomSlider.SmallChange = 1;
zoomSlider.LargeChange = 1;
zoomSlider.UseWaitCursor = false;
SetPictureBoxSize();
// reduce flickering
this.DoubleBuffered = true;
}
// picturebox size changed triggers paint event
private void SetPictureBoxSize()
{
Size s = new Size(Convert.ToInt32(imgOriginal.Width * zoomSlider.Value), Convert.ToInt32(imgOriginal.Height * zoomSlider.Value));
picBox.Size = s;
}
// looks for user trackbar changes
private void trackBar1_Scroll(object sender, EventArgs e)
{
if (zoomSlider.Value > 0)
{
SetPictureBoxSize();
}
}
// redraws image using nearest neighbour resampling
private void picBox_Paint_1(object sender, PaintEventArgs e)
{
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.DrawImage(
imgOriginal,
new Rectangle(0, 0, picBox.Width, picBox.Height),
// destination rectangle
0,
0, // upper-left corner of source rectangle
imgOriginal.Width, // width of source rectangle
imgOriginal.Height, // height of source rectangle
GraphicsUnit.Pixel);
}
Al cambiar el tamaño de una imagen en .net, System.Drawing.Drawing2D.InterpolationMode ofrece los siguientes métodos de cambio de tamaño:
- bicúbico
- bilineal
- Alto
- Alta calidad bicúbica
- Alta calidadBilineal
- Bajo
- Vecino más cercano
- Por defecto