Graphics.DrawImage не всегда закрашивает все растровое изображение?

Я столкнулся со странной проблемой при использовании Graphics.DrawImage.

При использовании e.Graphics.DrawImage(Image, Point) в OnPaint для рисования «буфера» растрового изображения в элементе управления кажется, что части изображения опущены. Буфер заполняется вспомогательным методом, который обращается непосредственно к Bitmap, используя Graphics, созданный из него. Когда элемент управления рисует, кэшированное растровое изображение отображается на элементе управления.

Кажется, что в самом растровом изображении ничего не пропущено, потому что, когда я сохранил растровое изображение на диск и исследовал его, все было там. (см. изображения ниже)

Вот как выглядит буфер растрового изображения:
 buffer
(источник: zachjohnson.net)

Вот что отображается на элементе управления:
 отображаемое значение
(источник: zachjohnson.net)

Это все, что я делаю в OnPaint:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    if (this.bufferInvalid)
    {
        this.UpdateBuffer();
    }

    if (this.buffer != null)
    {
        e.Graphics.DrawImage(this.buffer, Point.Empty);
    }
}

person Zach Johnson    schedule 29.11.2009    source источник
comment
Какие части опущены? Откуда взять растровое изображение? Что вы делаете, чтобы вызвать событие Paint?   -  person Guffa    schedule 29.11.2009
comment
Я отредактировал свой вопрос и добавил еще несколько деталей, включая изображения.   -  person Zach Johnson    schedule 29.11.2009


Ответы (3)


Когда вызывается OnPaint, Windows имеет недопустимую область, в которую можно рисовать, а все остальное обрезается. Если вы хотите обновить прямоугольный элемент управления, вы должны вызвать InvalidateRect в Windows API, чтобы убедиться, что весь прямоугольник является частью недопустимой области. OnPaint будет вызываться автоматически при обнаружении недействительной части элемента управления.

person Mark Ransom    schedule 29.11.2009
comment
Спасибо! Все, что мне нужно было сделать, это вызвать Control.Refresh() (который аннулирует и перерисовывает весь элемент управления). - person Zach Johnson; 30.11.2009
comment
Control.Invalidate () почти всегда лучше Control.Refresh (). - person Dan Byström; 30.11.2009

Вы можете попробовать несколько разных вещей.

  • разместите код в «UpdateBuffer»
  • выполните bitmap.save (т.е. buffer.save) после вызова updatebuffer и проверьте, как выглядит растровое изображение.
  • убедитесь, что сначала были нарисованы все элементы управления и что никакие элементы управления не отображаются прозрачными и т. д.
  • возьмите код «onpaint» и «буфер обновления» и поместите его в отдельный проект, чтобы проверить, работает ли он.
  • выньте "base.onpaint" и проверьте, что происходит
  • попробуйте вызвать bitmap.drawimageunscaled вместо bitmap.drawimage
  • попробуйте использовать новую точку (0,0) вместо point.empty (длинный выстрел, но я никогда не узнаю ...)

Тонны вариантов отладки, просто вопрос сужения.

person TryCatch    schedule 29.11.2009

Посмотрите System.Windows.Forms.ControlStyles.ResizeRedraw

person knockNrod    schedule 24.08.2010