Почему это графика.DrawImage обрезка часть моего изображения?
Если вы считаете следующее изображение, это довольно простой значок, размером 32x32. Вокруг значка прозрачный прямоугольник, хотя я заполнил четыре угла сплошным цветом во время тестирования.
Теперь рассмотрим этот код, который просто рисует изображение, но в большем масштабе:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.DrawImage(Properties.Resources.icon_32a, new RectangleF(0, 0, 512, 512), new RectangleF(0, 0, 32, 32), GraphicsUnit.Pixel);
}
обратите внимание, что я рисую полное изображение, и я не пытаюсь обрезать его каким-либо образом, просто увеличьте его.
наконец, это вывод теста дает мне:
замечать проблемы? Половина пикселей в верхнем ряду и левом столбце исчезли. Если я затем попытаюсь наложить сетку поверх этого, это выглядит довольно ужасно, поскольку сетка правильно выровнена, но изображение нет. Даже просто удвоив размер до 64, 64 вводит этот первый кадр строки/столбца.
Примечание, я также попытался смещать прямоугольник назначения на случай, если он рисовал до 0,0, но это не было случай.
Я также пытался использовать различные режимы интерполяции, но, насколько я мог судить через головную боль, вызывающую размытие, пиксели все еще были обрезаны, поэтому я не считаю, что это связано с режимом интерполяции.
Я также попытался использовать различные графические режимы, но помимо того, что это не помогло, мне все равно нужно придерживаться пикселей.
я попробовал снова с новой копией изображения на 96dpi из любопытства и получил тот же эффект, поэтому я не думаю, это разрешение исходных изображений.
хватаясь за соломинки и используя Rectangle
вместо RectangleF
также не имел никакого эффекта.
может ли кто-нибудь предложить какие-либо подсказки о том, почему этот очевидный урожай происходит?
спасибо;
2 ответов
на PixelOffsetMode
по умолчанию PixelOffsetMode.Half
:
указывает, что пиксели смещены на -.5 единиц по горизонтали и вертикально, для высокоскоростной сглаживания.
в вашем случае половина пикселя в исходном изображении составляет 8 пикселей в результирующем изображении, что именно то, что вам не хватает.
попробуйте установить его в PixelOffsetMode.None
:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.PixelOffsetMode = PixelOffsetMode.None;
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.DrawImage(Properties.Resources.icon_32a, new RectangleF(0, 0, 512, 512), new RectangleF(0, 0, 32, 32), GraphicsUnit.Pixel);
}
просто охватывая ответ, подтвержденный пользователями, я попробовал его сам, и проблема была решена с PixelOffsetMode.HighQuality
вместо none
.
в C#
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
мой случай c++ управляемый:
e->graphics->PixelOffsetMode = System::Drawing::Drawing2D::PixelOffsetMode::HighQuality;