2015-07-26 2 views
1

Интересно, есть ли простой способ обновить только часть графики? В приведенном ниже примере я нарисовал 1560 маленьких квадратов размером 10x10 пикселей каждый и покрасил синим 3 из них. Это занимает некоторое значительное время (около 1 сек.), Можно увидеть, как они окрашиваются на экран. На следующем шаге я хотел бы переместить 3 синих квадрата на другую позицию, то есть я хочу сохранить всю нарисованную графику, но рисуем только 3 квадрата до серого цвета и рисуем еще 3 sqares до синего. Если я полностью перекрашу изображение, это займет много времени, прибл. 1 сек. упомянутое выше. Я хотел бы достичь как минимум нескольких кадров в секунду, поскольку я делаю небольшую «анимированную» симуляцию. Это означает, что код не должен быть сексуальным, но достаточно простым, чтобы его можно было использовать в программе с очень коротким проживанием.Обновление только части графики

Pattern of squares

Метод набросал в button4_Click код быстро, но только потому, что краски только новые квадраты, уничтожив старые графики.

Обратите внимание, что я рисую на Panel1, а не на PictureBox1, как это рекомендуется из-за производительности (избегая некоторых ненужных обработчиков событий и обновляет).

Sketched код теста:

Private drawPattern As Boolean = False 
Private drawBlueRects As Boolean = False 
Dim blueBrush As New SolidBrush(Color.Blue) 
Dim grayBrush As New SolidBrush(Color.Gray) 

Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint 
    Dim g As Graphics = e.Graphics 
    If drawPattern Then 
     Dim StartY As Integer = 250 - 60 ' just set Y for upper set of squares 
     For ir = 1 To 6     ' paint upper set of squares 
      For ic = 0 To 120 
       g.DrawRectangle(New Pen(Color.Gray), 5 + ic * 10, StartY + ir * 10, 8, 8) 
      Next 
     Next ir 
     StartY = 250 + 10 ' just set Y for bottom set of squares 
     For ir = 1 To 6 ' paint bottom set of squares 
      For ic = 0 To 120 
       g.DrawRectangle(New Pen(Color.Gray), 5 + ic * 10, StartY + ir * 10, 8, 8) 
      Next 
     Next ir 
     For ic = 0 To 120 ' paint middle set of squares 
      g.FillRectangle(grayBrush, 5 + ic * 10, 250 + 10, 8, 8) 
     Next 
     ' paint 3 blue squares 
     g.FillRectangle(blueBrush, 155, 250 + 10, 8, 8) 
     g.FillRectangle(blueBrush, 165, 250 + 10, 8, 8) 
     g.FillRectangle(blueBrush, 175, 250 + 10, 8, 8) 
    ElseIf drawBlueRects = True Then 
     ' paint 3 blue squares 
     g.FillRectangle(blueBrush, 255, 250 + 10, 8, 8) 
     g.FillRectangle(blueBrush, 265, 250 + 10, 8, 8) 
     g.FillRectangle(blueBrush, 275, 250 + 10, 8, 8) 
    End If 
End Sub 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    drawPattern = True 
    Panel1.Refresh() 
    'Panel1.Refresh() 
End Sub 

Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click 
    drawPattern = False 
    drawBlueRects = True 
    Panel1.Refresh() 
End Sub 

Я извиняюсь, если я misgoogled готовое решение; пожалуйста, укажите ссылку в таком случае.

Привет,

Libor

ответ

0

Способ управления Invalidate определяет, что конкретная область управления должна быть перекрашены и метод Update инициирует перерисовку. Метод Refresh просто вызывает Invalidate без параметров, что указывает на необходимость перекраски всего элемента управления, а затем вызывает Update. Вместо Refresh позвоните по телефону Invalidate и Update самостоятельно. Таким образом, вы можете передать соответствующий аргумент Invalidate, чтобы точно указать, какую часть или части элемента управления нужно перерисовать. Вы можете позвонить Invalidate несколько раз для сложной области или областей.

+0

я решил отметить это, как правильный ответ, потому что это. Однако я столкнулся с проблемой, которую я объясняю ниже. –

0

Я решил проблему обходным путем - я рисую растровое изображение и обновляю PictureBox с помощью этого растрового изображения каждый раз, когда меняю его. Так как я могу обратить особое расположение растрового изображения, нет никаких проблем с перерисовывая:

Определение растрового изображения в классе рубрике:

Dim bm As New Bitmap(1910, 500) 

первоначальный рисунок:

Private Sub CreateImage() 
    Dim w As Integer = bm.Width ' or PictureBox1.Width 
    Dim h As Integer = bm.Height ' or PictureBox1.Height 
    Dim bmp As New Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb) 
    bm = bmp 
    Using g As Graphics = Graphics.FromImage(bmp) ' get it from current state of bitmap 
     Me.DoubleBuffered = True 
     Dim Ypos As Integer = 0 
     Call DrawRecArray(StartY - 100, g, NoOfBaysInSet) 
     Call DrawRecArray(StartY + 10, g, NoOfBaysInSet) 
     For ic = 0 To icLimit ' paint middle set of squares 
      g.FillRectangle(grayBrush, 5 + ic * 10, StartY + 10, 8, 8) 
      Call DrawStringFunc(5 + ic * 10, StartY - 70 + Ypos * 5, ic + 1, g, drawFont) 
      Ypos += 1 
      If Ypos = 3 Then Ypos = 0 
      If Ypos = 1 Then Call DrawStringFunc(5 + ic * 10, StartY - 90 + Ypos * 5, (ic + 1 * 3)/3, g, drawFontB) 
     Next 
    End Using 
    PictureBox1.Image = bmp ' put the bitmap into Picturebox !!! 
End Sub 

Обновления растровое изображение:

Private Sub UpdateImage(FromPos As Int16, ToPos As Int16) 
    Dim w As Integer = bm.Width 
    Dim h As Integer = bm.Height 
    Dim bmp As New Bitmap(Me.PictureBox1.Image) ' now get the bitmap from the PictureBox 
    bm = bmp 
    Using g As Graphics = Graphics.FromImage(bmp) 
     Me.DoubleBuffered = True 
     g.FillRectangle(backBrush, 5 + FromPos * 10, StartY + 10, 28, 8) 
     g.FillRectangle(grayBrush, 5 + FromPos * 10, StartY + 10, 8, 8) 
     g.FillRectangle(grayBrush, 15 + FromPos * 10, StartY + 10, 8, 8) 
     g.FillRectangle(grayBrush, 25 + FromPos * 10, StartY + 10, 8, 8) 
     g.FillRectangle(blueBrush, 5 + ToPos * 10, StartY + 10, 28, 8) 
    End Using 
    PictureBox1.Image = bmp ' update pictureBox with modified bitmap 
End Sub 

Я считаю, что это ценный ответ. Я имею дело с GDI в течение нескольких лет и неоднократно сталкивался с этой проблемой и из многих тысяч ответов, лишь немногие описывают перерисовку без события _paint, которое, по моему мнению, бесполезно для таких случаев. Большинство образцов являются одноразовыми чертежами.

С уважением

Libor

Смежные вопросы