Почему Graphics.DrawImage обрезает часть моего изображения?

Если вы считаете следующее изображение, это довольно простой значок размером 32x32. Вокруг иконки есть прозрачный прямоугольник, хотя во время тестирования я заполнил четыре угла сплошным цветом.

Source Image

Теперь рассмотрим этот код, который просто рисует изображение, но в большем масштабе:

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);
}

Обратите внимание, что я рисую полный образ, и я никоим образом не пытаюсь обрезать его, просто увеличьте его.

Наконец, это результат, который дает мне тест:

Painted example

Обратите внимание на проблему? Половина пикселей в верхней и левой колонках исчезла. Если я затем попытаюсь наложить сетку поверх этого, это выглядит довольно ужасно, так как сетка правильно выровнена, но изображение отсутствует. Даже удваивая размер до 64, 64 вводит этот первый столбец строки/столбца.

Заметьте, я также попытался смещать прямоугольник назначения на всякий случай, когда он рисовал до 0,0, но это было не так.

Я также пробовал использовать разные режимы интерполяции, но, насколько я мог сказать, из-за головной боли, вызывающей размытие, пиксели все еще были обрезаны, поэтому я не верю, что это связано с режимом интерполяции.

Я также попытался использовать разные графические режимы, но, помимо того, что это не помогло, мне все равно нужно придерживаться пикселей.

Я попытался снова с новой копией изображения на 96dpi из любопытства и получил тот же эффект, поэтому я не думаю, что это разрешение исходных изображений.

Сжатие на соломинках и использование Rectangle вместо RectangleF также не повлияло.

Может ли кто-нибудь предложить какие-либо подсказки относительно того, почему этот кажущийся урожай происходит?

Благодаря;

7
nl ja de

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);
}
7
добавлено
У меня была такая же проблема. Также не было известно о свойстве PixelOffsetMode . Опять же, PixelOffsetMode.None не работал для меня, несмотря на очевидную настройку, но PixelOffsetMode.HighQuality действительно работал.
добавлено автор Chris Walsh, источник
Ротем, спасибо за ваш ответ - я не знал об этом конкретном имуществе. Я тестировал его, но он все еще не работал. Тем не менее, я обнаружил, что если я установил его HighQuality , тогда мое изображение было отображено правильно. Звучит как глупое значение по умолчанию для меня, но легко исправить, если вы знаете - еще раз спасибо!
добавлено автор Richard Moss, источник

Просто прикрывая ответ, подтвержденный пользователями, я сам его пробовал, и проблема была решена с помощью PixelOffsetMode.HighQuality вместо none .

C #

e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

мой код c ++:

e->graphics->PixelOffsetMode = System::Drawing::Drawing2D::PixelOffsetMode::HighQuality;
1
добавлено
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot