VB.NET Find a Pixel Color of an Image - vb.net

How Can I find the HEX color of a specific image pixel? I've Tried This:
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
PictureBox1.Image = Image.FromFile("c:\image.jpg")
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
Dim b As Bitmap = Me.PictureBox1.Image
Dim ver As String = b.GetPixel(e.X, e.Y).ToString
Dim veri As String = Hex(b.GetPixel(e.X, e.Y).ToArgb)
End Sub
This doesn't work as expected:
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
PictureBox1.Image = My.Resources.MyImage
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
Dim b As Bitmap = Me.PictureBox1.Image 'b is not streched..?
Dim ver As String = b.GetPixel(e.X, e.Y).ToString
Dim veri As String = Hex(b.GetPixel(e.X, e.Y).ToArgb)
End Sub
How can I fix this?

I'll post this as an answer because I want to post some code. You seem to be under the impression that setting the SizeMode of a PictureBox does/should affect the Image it contains. It doesn't and it shouldn't. That property is for the UI only, i.e. it affects what the user sees but has no effect on the data. To prove that to yourself, try creating a WinForms app with two PictureBoxes and two Buttons and add this code:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
PictureBox1.Image = Image.FromFile("image file path here")
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If PictureBox1.SizeMode = PictureBoxSizeMode.Normal Then
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
Else
PictureBox1.SizeMode = PictureBoxSizeMode.Normal
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
PictureBox2.Image = PictureBox1.Image
MessageBox.Show(PictureBox2.Image.Size.ToString())
End Sub
You can set the image path to any file you want.
If you click Button2 you'll see the same image appear in PictureBox2 as in PictureBox1 and the dimensions will be displayed. If you click Button1 you'll see the image in PictureBox1 change dimensions to fit the control. If you click Button2 again, what you see in PictureBox2 won't change and neither will the dimensions displayed, because the Image object hasn't changed.
If you want to get the colour of the pixel under the mouse cursor then you'd need to call DrawToBitmap on the control itself to get a Bitmap of what's actually displayed on the screen.

Related

PictureBox2.Image = PictureBox1.Image seems to be linking the boxes instead of copying the image over?

The Problem
I have a simple form with 2 PictureBoxes
I allow the user to draw on PictureBox1
When I click a Button on the form I want to capture the image in PictureBox1 and store it in PictureBox2
The issue is that if I add the line:
PictureBox2.Image = PictureBox1.Image
Any updates to PictureBox1 are immediately reflected in PictureBox2 ?!?
I just want to capture the image in PictureBox1 at that moment in time so that I can use it to 'Undo'
Tech
It's a Windows Forms App in Visual Basic, .Net 4.7.2 using Visual Studio 2019 Preview
Code
Public Class Form1
Dim drawMouseDown = False ' Set initial mouse state to not clicked
Dim drawMyBrush As New Pen(Brushes.White, 20) 'Set up the Brush
Public drawCanvas As New Bitmap(245, 352) 'Set up Bitmap Canvas
Private Sub btn_Color_Yellow_Click(sender As Object, e As EventArgs) Handles btn_Color_Yellow.Click
drawMyBrush.Brush = Brushes.Yellow
drawMyBrush.Width = 20
End Sub
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
drawMouseDown = True
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
drawMouseDown = False
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
Dim g As Graphics = Graphics.FromImage(drawCanvas)
Static coord As New Point
If drawMouseDown Then
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
drawMyBrush.StartCap = Drawing2D.LineCap.Round
drawMyBrush.EndCap = Drawing2D.LineCap.Round
g.DrawLine(drawMyBrush, coord.X, coord.Y, e.X, e.Y)
g.Dispose()
PictureBox1.Image = drawCanvas
Me.Refresh()
End If
coord = e.Location
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PictureBox2.Image = PictureBox1.Image 'Why does this not just update the PicBox2 image once?!? (or only when the Button is clicked)
End Sub
End Class
Expectation
When Button1 is clicked I expect PictureBox2 to contain the PictureBox1 image, when I continue to draw on PictureBox1 I do NOT expect it to keep updating PictureBox2 as the user is drawing on the other!
As you suspect, PictureBox2.Image = PictureBox1.Image makes the former a reference to the latter.
What you can do instead is clone the image:
PictureBox2.Image = DirectCast(PictureBox1.Image.Clone(), Image)
Because you are referencing the Image property of PictureBox2 to PictureBox1.Image. So when they both point to the same reference, any changes to either of the PictureBox's image property, will affect the other's.
In order to avoid his, make a new instance of Bitmap object based on the PictureBox1.Image and set it to PictureBox2.Image:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PictureBox2.Image = New Bitmap(PictureBox1.Image)
End Sub

How do we show the previous image in a picturebox in VB.net?

I have stored the images in an array, after that, I have added an if statement to check which image is currently showing, here is my code so far but there are no results.
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim img(3) As Image
img(0) = My.Resources.bugs
img(1) = My.Resources.discuss
img(2) = My.Resources.flower
img(3) = My.Resources.mask
If PictureBox1.Image Is img(0) Then
PictureBox1.Image = img(3)
End If
End Sub
There's a serious issue with your code. You should NOT access the same property of My.Resources over and over like that. That's because it extracts the data and creates a new object every time, so you will be creating four new Image objects every time the user clicks that Button. You should extract the resources and populate the array once only.
That's the reason that your If statement doesn't work. Even if they are created from the same resource, the Image object currently in the PictureBox is not the same object as is in your array.
You should store the index of the current image in a field and then, each time you want to go to the next image, you simply increment that field and get the Image at that index. You can use Mod to wrap at the end of the array.
Private images As Image() = {My.Resources.bugs,
My.Resources.discuss,
My.Resources.flower,
My.Resources.mask}
Private imageIndex As Integer = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
PictureBox1.Image = images(imageIndex)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
imageIndex = (imageIndex + 1) Mod images.Length
PictureBox1.Image = images(imageIndex)
End Sub
I missed that you said "previous" rather than "next". This will work for that:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
imageIndex -= 1
If imageIndex < 0 Then
imageIndex = images.GetUpperBound(0)
End If
PictureBox1.Image = images(imageIndex)
End Sub

How do I convert picturebox.click event into a button.click event

I'm trying to have two options to draw a border around a picture box.
I can click on the picturebox to highlight but now would like to be able to use a button to do the same thing.
Private Sub imgLabel_Click(sender As Object, e As EventArgs) Handles imgLabel.Click
Dim BorderBounds As Rectangle = DirectCast(sender, PictureBox).ClientRectangle BorderBounds.Inflate(-1, -1)
ControlPaint.DrawBorder(DirectCast(sender, PictureBox).CreateGraphics, BorderBounds, Color.Orange, ButtonBorderStyle.Solid)
If Not (HighLightededPictureBox Is Nothing) Then
HighLightededPictureBox.Invalidate()
End If
'Rememeber the last highlighted PictureBox  
HighLightededPictureBox = CType(sender, PictureBox)
When I try to add a button click I get the Exception Unhandled - System.windows.forms.button to type System.windows.forms.picturebox error.
I have tried to add the button click event after "Handles" which causes the above error.
Private Sub imgLabel_Click(sender As Object, e As EventArgs) Handles imgLabel.Click, button1.click
I'm pretty new to programming and my searching results are turning anything up of value. I don't fully understand Ctypes/Directcasts.
Any help is greatly appreciated.
Ok, so I ended up going with this...
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim boxsize As New Size(192, 169)
Dim recpoint As New Point(0, 0)
Dim myrectangle As New Rectangle(recpoint, boxsize)
myrectangle.Inflate(-3, -3)
Dim G As Drawing.Graphics = PictureBox1.CreateGraphics
Dim Pen As New Pen(Color.Orange, 5)
G.DrawRectangle(Pen, myrectangle)
End Sub
Seems to be working ok, but requires a lot of manual entry of points. I have 6 more of these.
You could try
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
imgLabel_Click(imgLabel, nothing)
End Sub

Display an image in picturebox from specific position

I have a picturebox that "works" as button. I have load an image map as background image, to use it for buttons conditions (click, hover etc).
As default, background image shows it's top left position, the first icon. Let's say, how can I move (x) to 32px and (y) to 64? Something like css styles background-position: 32px 64px; for example.
If you need to reposition the image then I wouldn't use a PictureBox, just a Panel or draw the image on the surface of the form.
It is possible though with the following code. Notice that it removes the PictureBox's Image so you are losing the functionality of a PictureBox.
Public Class Form1
Private _moveIt As Boolean = False
Private _coyote As Image
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
_coyote = PictureBox1.Image
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
_moveIt = True
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
If _moveIt = True Then
PictureBox1.Image = Nothing
e.Graphics.DrawImage(_coyote, New Rectangle(New Point(32, 64), _
New Size(_coyote.Width, _coyote.Height)))
End If
End Sub
End Class
To keep the PcitureBox's functionality (to use its Image property) you would have to create a new image which is a transformed version of the original image.

Draw graphics on screen

I am using Visual Basic.Net and am drawing graphics on the screen.
Here is my code:
Private Sub Button1_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Button1.Click
Dim gr As Graphics = Graphics.FromHwnd(New IntPtr(0))
gr.DrawString("text on screen",
New Font(Me.Font.FontFamily, 25,
FontStyle.Regular), Brushes.Red, 50, 50)
End Sub
In the above code, text is drawn on the screen. My question is this: How can I remove the text that is drawn to screen? I see that there is a .Clear method, however, this 'Clears the entire drawing surface and fills it with the specified background color', rather than just removing the drawn text.
Thanks in advance.
EDIT
I am wanting to develop a subliminal message application that will show messages on screen while the user is using other applications. Would the transparent form be the best way to do this?
I have found the following code that works:
Private WithEvents TextForm As New Form
Private Zipper As New FontFamily("Zipper")
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
With TextForm
.BackColor = Color.DimGray
.TransparencyKey = Color.DimGray
.FormBorderStyle = Windows.Forms.FormBorderStyle.None
.ShowInTaskbar = False
.WindowState = FormWindowState.Maximized
.Opacity = 0
.Show(Me)
End With
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Static showText As Boolean
showText = Not showText
If showText Then TextForm.Opacity = 0.99 Else TextForm.Opacity = 0
End Sub
Private Sub TextForm_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles TextForm.Paint
e.Graphics.DrawString("text on screen 12345", New Font(Zipper, 30, FontStyle.Bold), Brushes.Red, 50, 50)
End Sub
Take different bitmaps and draw each new thing in separate bitmaps and after merge new bitmap with old one. When you want to remove text reload old bitmap which is without text.
Search for drawing in new bitmaps and save drawing.
You can try this:
Dim Graphics0 as Graphics = Graphics.fromHwnd(0) 'This is the desktop's graphics
Graphics0.DrawText("Test 1..2..3..",New Font(Arial,10),Brushes.Black,New Point(0,0))