Как заставить PictureBox использовать передискретизацию ближайшего соседа?
-
09-06-2019 - |
Вопрос
Я использую StretchImage, потому что размер поля можно изменить с помощью разделителей.Похоже, что по умолчанию используется какая-то плавная билинейная фильтрация, из-за которой мое изображение становится размытым и имеет муаровый узор.
Решение
Мне тоже нужна была эта функция.Я создал класс, который наследует PictureBox, переопределяет OnPaint
и добавляет свойство, позволяющее установить режим интерполяции:
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);
}
}
Другие советы
Я подозреваю, что вам придется изменить размер вручную с помощью класса Image и функции DrawImage и реагировать на события изменения размера в PictureBox.
Я провел поиск в MSDN и обнаружил, что об этом есть статья, которая не очень подробная, но описывает, что вам следует использовать событие рисования.
http://msdn.microsoft.com/en-us/library/k0fsyd4e.aspx
Я отредактировал общедоступный пример масштабирования изображения, чтобы использовать эту функцию, см. ниже.
Отредактировано: http://www.dotnetcurry.com/ShowArticle.aspx?ID=196&AspxAutoDetectCookieSupport=1
Надеюсь это поможет
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);
}
При изменении размера изображения в .net System.Drawing.Drawing2D.InterpolationMode предлагает следующие методы изменения размера:
- Бикубический
- Билинейный
- Высокий
- Высокое качествоБикубический
- Высокое качествоБилинейный
- Низкий
- Ближайший сосед
- По умолчанию