在VB.net表单中更改像素颜色?

3
我该如何在 VB.NET 表单中更改单个像素的颜色?
谢谢。

你能否在这里再明确一些?你为什么想要改变单个像素? - Caffeinated
Stack Overflow不是你的个人研究助手。 - Oded
我正在制作一个显示Mandelbrot集合的程序,需要在窗体上更改单个像素的颜色,因为每个像素都代表图形上的一个点,因此具有自己的颜色。 - SiliconCelery
3
哇,别这么激动。我已经尽可能做了谷歌搜索,大部分结果都是有关检测单个像素颜色的帮助,而我找到的有关设置像素颜色的仅会导致语法错误。我知道这不是特别高级的编程问题,但我只是希望有人能至少指点我一下方向。 - SiliconCelery
3个回答

2
Winforms的一个硬性要求是,你应该能够在Windows要求时重新绘制窗体。这将在最小化和还原窗口时发生。或者在旧版本的Windows上,当你将另一个窗口移动到你的窗口上方时也会发生。
所以,仅在窗口上设置像素是不够的,当窗口重绘时你将失去所有像素。相反,使用位图。另外,你需要保持用户界面的响应性,因此需要在工作线程上进行计算。BackgroundWorker很方便可以让你做对的事情。
一种方法是使用两个位图,一个用于在工作线程中填充,另一个用于显示。每处理完一行像素就复制正在工作的位图并将其传递给ReportProgress()方法。然后你的ProgressChanged事件释放旧的位图并存储新的传递位图,然后调用Invalidate来强制重绘。

0

1
谢谢你的帮助,但我真正需要的是改变像素的颜色,而不是获取它们的颜色。我知道的唯一解决方案是为屏幕上的每个像素创建一个图片框,并更改它们的颜色,但这似乎非常低效。 - SiliconCelery

0
这是一些演示代码。如Hans所述,重绘速度很慢。加快速度的简单方法是延迟后仅重新计算位图。
Public Class Form1

  Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    'create new bitmap

    If Me.ClientRectangle.Width <= 0 Then Exit Sub
    If Me.ClientRectangle.Height <= 0 Then Exit Sub

    Using bmpNew As New Bitmap(Me.ClientRectangle.Width, Me.ClientRectangle.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
      'draw some coloured pixels
      Using g As Graphics = Graphics.FromImage(bmpNew)
        For x As Integer = 0 To bmpNew.Width - 1
          For y As Integer = 0 To bmpNew.Height - 1
            Dim intR As Integer = CInt(255 * (x / (bmpNew.Width - 1)))
            Dim intG As Integer = CInt(255 * (y / (bmpNew.Height - 1)))
            Dim intB As Integer = CInt(255 * ((x + y) / (bmpNew.Width + bmpNew.Height - 2)))
            Using penNew As New Pen(Color.FromArgb(255, intR, intG, intB))
              'NOTE: when the form resizes, only the new section is painted, according to e.ClipRectangle.
              g.DrawRectangle(penNew, New Rectangle(New Point(x, y), New Size(1, 1)))
            End Using
          Next y
        Next x
      End Using
      e.Graphics.DrawImage(bmpNew, New Point(0, 0))
    End Using

  End Sub

  Private Sub Form1_ResizeEnd(sender As Object, e As System.EventArgs) Handles Me.ResizeEnd
    Me.Invalidate() 'NOTE: when form resizes, only the new section is painted, according to e.ClipRectangle in Form1_Paint(). We invalidate the whole form here to form an  entire form repaint, since we are calculating the colour of the pixel from the size of the form. Try commenting out this line to see the difference.
  End Sub

End Class

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接