如何避免 graphics.drawrectangle() 上的不透明矩形重叠?
How to avoid overlapping of opaque rectangles on graphics.drawrectangle()?
在 Google 搜索失败后,我终于想到请专家来帮助我解决这个问题,因为这个网站总是帮助我。
我想要什么?
I want to create a Highlighter for my some kind of drawing application. I want this to be similar to the highlighter you can see on the Windows Snipping Tool.
我的问题是什么?
The problem is that although I can draw the semitransparent or opaque rectangles using the code, gfx.FillRectangle(New SolidBrush(Color.FromArgb(100, Colors.GreenYellow)), x, y, width, height)
, but if I draw another rectangle overlapping any previous rectangles the colors gets darker and reduces the transparency of the rectangles where they overlapped.
代码:
Public Class Form1
Dim drag As Boolean
Dim mouseX, mouseY As Integer
Dim prev As Point
Dim initi As Point
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Dim grx As Graphics = Panel1.CreateGraphics
grx.DrawString("+", New Font("Arial", 144, FontStyle.Regular), New SolidBrush(Color.FromArgb(100, Color.GreenYellow)), New Point(200, 200))
End Sub
Private Sub Panel1_MouseDown(sender As Object, e As MouseEventArgs) Handles Panel1.MouseDown
drag = True
mouseX = MousePosition.X - Me.Left - 8
mouseY = MousePosition.Y - Me.Top - 34
initi = New Point(mouseX, mouseY)
End Sub
Private Sub Panel1_MouseMove(sender As Object, e As MouseEventArgs) Handles Panel1.MouseMove
If drag Then
mouseX = MousePosition.X - Me.Left - 8
mouseY = MousePosition.Y - Me.Top - 34
End If
End Sub
Private Sub Panel1_MouseUp(sender As Object, e As MouseEventArgs) Handles Panel1.MouseUp
drag = False
prev = New Point(0, 0)
Dim grx As Graphics = Panel1.CreateGraphics
grx.FillRectangle(New SolidBrush(Color.FromArgb(100, Color.GreenYellow)), initi.X, initi.Y, (mouseX - initi.X), (mouseY - initi.Y))
End Sub
End Class
应用程序的屏幕截图(显示问题)
- 左边的“+”是我要画的
- 右边的“+”是我画的时候得到的那个。
我试过了,效果很好:没有边框,你甚至无法区分不同的盒子:
我更改了以下内容:
New SolidBrush(Color.FromArgb(100, Color.GreenYellow)), New Point(200, 200))
进入这个:
New SolidBrush(Color.GreenYellow), New Point(200, 200))
两次:对于声明和 Panel1_MouseDown
这是因为默认情况下这会将 Alpha 设置为 1,因此也无法更改,因此重叠不会更改任何颜色、图层或可见性。
您应该只在要控制颜色的 alpha 时使用 FromArgb
,但在这种情况下,您是让计算机为您做这件事
嗯。我从来没有真正使用过图形,但我唯一能想到的就是创建一个要绘制的高光列表,然后每次 mouse_up 事件触发时,创建一个新的位图,绘制每个矩形像素按像素,将半透明像素绘制到位图,然后使用刷新面板时触发的面板的绘制事件处理程序将生成的位图绘制到面板。这似乎是 .net 自动执行的内置 alpha 混合。
将此添加到表单的变量声明中
Dim highlightsList As New List(Of Rectangle)
Dim bmp1 As Bitmap
将您的 form_shown 活动更改为
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
bmp1 = New Bitmap(Panel1.Width, Panel1.Height)
End Sub
添加这个处理将矩形添加到列表和创建位图的子程序
Private Sub addRectangle(gr As Graphics, x As Integer, y As Integer, v1 As Integer, v2 As Integer)
Dim newRectangle As New Rectangle(x, y, v1, v2)
highlightsList.Add(newRectangle)
Using G As Graphics = Graphics.FromImage(bmp1)
G.Clear(Color.White)
End Using
bmp1.MakeTransparent(Color.White)
For Each rect As Rectangle In highlightsList
For i As Integer = rect.X To rect.X + rect.Width - 1
For j As Integer = rect.Y To rect.Y + rect.Height - 1
bmp1.SetPixel(i, j, Color.FromArgb(100, Color.GreenYellow))
Next
Next
Next
Panel1.Refresh()
End Sub
为面板的绘制事件添加一个处理程序,这样当您刷新面板时,位图就会被绘制到上面
Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
e.Graphics.DrawImage(bmp1, 0, 0)
End Sub
并更改您的 mouse_up 事件以使用上述子项进行绘图
Private Sub Panel1_MouseUp(sender As Object, e As MouseEventArgs) Handles Panel1.MouseUp
drag = False
prev = New Point(0, 0)
Dim grx As Graphics = Panel1.CreateGraphics
'grx.Clear(Panel1.BackColor)
addRectangle(grx, initi.X, initi.Y, (mouseX - initi.X), (mouseY - initi.Y))
End Sub
这似乎可行,但如果您将面板用于显示高亮显示的任何其他内容,它可能无法按预期工作。
在 Google 搜索失败后,我终于想到请专家来帮助我解决这个问题,因为这个网站总是帮助我。
我想要什么?
I want to create a Highlighter for my some kind of drawing application. I want this to be similar to the highlighter you can see on the Windows Snipping Tool.
我的问题是什么?
The problem is that although I can draw the semitransparent or opaque rectangles using the code,
gfx.FillRectangle(New SolidBrush(Color.FromArgb(100, Colors.GreenYellow)), x, y, width, height)
, but if I draw another rectangle overlapping any previous rectangles the colors gets darker and reduces the transparency of the rectangles where they overlapped.
代码:
Public Class Form1
Dim drag As Boolean
Dim mouseX, mouseY As Integer
Dim prev As Point
Dim initi As Point
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Dim grx As Graphics = Panel1.CreateGraphics
grx.DrawString("+", New Font("Arial", 144, FontStyle.Regular), New SolidBrush(Color.FromArgb(100, Color.GreenYellow)), New Point(200, 200))
End Sub
Private Sub Panel1_MouseDown(sender As Object, e As MouseEventArgs) Handles Panel1.MouseDown
drag = True
mouseX = MousePosition.X - Me.Left - 8
mouseY = MousePosition.Y - Me.Top - 34
initi = New Point(mouseX, mouseY)
End Sub
Private Sub Panel1_MouseMove(sender As Object, e As MouseEventArgs) Handles Panel1.MouseMove
If drag Then
mouseX = MousePosition.X - Me.Left - 8
mouseY = MousePosition.Y - Me.Top - 34
End If
End Sub
Private Sub Panel1_MouseUp(sender As Object, e As MouseEventArgs) Handles Panel1.MouseUp
drag = False
prev = New Point(0, 0)
Dim grx As Graphics = Panel1.CreateGraphics
grx.FillRectangle(New SolidBrush(Color.FromArgb(100, Color.GreenYellow)), initi.X, initi.Y, (mouseX - initi.X), (mouseY - initi.Y))
End Sub
End Class
应用程序的屏幕截图(显示问题)
- 左边的“+”是我要画的
- 右边的“+”是我画的时候得到的那个。
我试过了,效果很好:没有边框,你甚至无法区分不同的盒子: 我更改了以下内容:
New SolidBrush(Color.FromArgb(100, Color.GreenYellow)), New Point(200, 200))
进入这个:
New SolidBrush(Color.GreenYellow), New Point(200, 200))
两次:对于声明和 Panel1_MouseDown
这是因为默认情况下这会将 Alpha 设置为 1,因此也无法更改,因此重叠不会更改任何颜色、图层或可见性。
您应该只在要控制颜色的 alpha 时使用 FromArgb
,但在这种情况下,您是让计算机为您做这件事
嗯。我从来没有真正使用过图形,但我唯一能想到的就是创建一个要绘制的高光列表,然后每次 mouse_up 事件触发时,创建一个新的位图,绘制每个矩形像素按像素,将半透明像素绘制到位图,然后使用刷新面板时触发的面板的绘制事件处理程序将生成的位图绘制到面板。这似乎是 .net 自动执行的内置 alpha 混合。
将此添加到表单的变量声明中
Dim highlightsList As New List(Of Rectangle)
Dim bmp1 As Bitmap
将您的 form_shown 活动更改为
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
bmp1 = New Bitmap(Panel1.Width, Panel1.Height)
End Sub
添加这个处理将矩形添加到列表和创建位图的子程序
Private Sub addRectangle(gr As Graphics, x As Integer, y As Integer, v1 As Integer, v2 As Integer)
Dim newRectangle As New Rectangle(x, y, v1, v2)
highlightsList.Add(newRectangle)
Using G As Graphics = Graphics.FromImage(bmp1)
G.Clear(Color.White)
End Using
bmp1.MakeTransparent(Color.White)
For Each rect As Rectangle In highlightsList
For i As Integer = rect.X To rect.X + rect.Width - 1
For j As Integer = rect.Y To rect.Y + rect.Height - 1
bmp1.SetPixel(i, j, Color.FromArgb(100, Color.GreenYellow))
Next
Next
Next
Panel1.Refresh()
End Sub
为面板的绘制事件添加一个处理程序,这样当您刷新面板时,位图就会被绘制到上面
Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
e.Graphics.DrawImage(bmp1, 0, 0)
End Sub
并更改您的 mouse_up 事件以使用上述子项进行绘图
Private Sub Panel1_MouseUp(sender As Object, e As MouseEventArgs) Handles Panel1.MouseUp
drag = False
prev = New Point(0, 0)
Dim grx As Graphics = Panel1.CreateGraphics
'grx.Clear(Panel1.BackColor)
addRectangle(grx, initi.X, initi.Y, (mouseX - initi.X), (mouseY - initi.Y))
End Sub
这似乎可行,但如果您将面板用于显示高亮显示的任何其他内容,它可能无法按预期工作。