I am coding a program that edits pictures, I have a picture box where I load a bitmap, the first image loads fine, but if I want to load a second image, the second image won't load and the first one stays, it won't refresh. How can I do to change the image in the picture box using 2 different bitmaps?
I have PictureBox3.Image = bm where bm is a bitmap variable, it loads fine, but then if I press the other button to load another bitmap in PictureBox3 (PictureBox3.Image = bm2), it won't load.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim clr As Integer
Dim ymax As Integer
Dim xmax As Integer
Dim x As Integer
Dim y As Integer
Dim bm As Bitmap = PictureBox1.Image
xmax = bm.Width - 1
ymax = bm.Height - 1
For y = 0 To ymax
For x = 0 To xmax
With bm.GetPixel(x, y)
clr = 0.21 * .R + 0.72 * .G + 0.07 * .B
End With
bm.SetPixel(x, y, _
Color.FromArgb(255, clr, clr, clr))
Next x
Next y
PictureBox3.Image = bm
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim clr As Integer
Dim ymax As Integer
Dim xmax As Integer
Dim x As Integer
Dim y As Integer
Dim bm2 As Bitmap = PictureBox1.Image
xmax = bm2.Width - 1
ymax = bm2.Height - 1
For y = 0 To ymax
For x = 0 To xmax
With bm2.GetPixel(x, y)
clr = (1 * .R + 1 * .G + 1 * .B) / 3
End With
bm2.SetPixel(x, y, _
Color.FromArgb(255, clr, clr, clr))
Next x
Next y
PictureBox3.Image = bm2
End Sub
End Class
Dim bm2 As Bitmap = new Bitmap(PictureBox1.Image)
Related
I have to create a program that reduces image size by reducing color. I got this code from my friend. Can you check it out? Thank you for your help.
Imports System.Drawing.Imaging
Public Class Form1
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim ofd As New OpenFileDialog()
If ofd.ShowDialog() = DialogResult.OK Then
Dim bmp As New Bitmap(ofd.FileName)
PictureBox.Image = bmp
Dim width As Integer = bmp.Width
Dim height As Integer = bmp.Height
Dim bmr As New Bitmap(height, height)
For i = 0 To width - 1
For j = 0 To height - 1
Dim a,b,c As Integer
Dim color As New Color
color = bmp.GetPixel(i, j)
a = color.a / 2
b = color.b / 2
c = color.c / 2
bmr.SetPixel(i, j, Color.FromArgb(a,b,c ))
a = 0 : b = 0 : c = 0
Next
Next
PictureBox2.Image = bmr
bmr.Save("image2.jpg", Imaging.ImageFormat.Jpeg)
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim ofd As New OpenFileDialog()
Dim imgSource As String
If ofd.ShowDialog() = DialogResult.OK Then
imgSource = ofd.FileName
Dim bmp As New Bitmap(ofd.FileName)
PictureBox.Image = bmp
Dim wid As Integer = ((bmp.Width / 2) + 1)
Dim hgt As Integer = ((bmp.Height / 2) + 1)
Dim bmr As New Bitmap(wid, hgt)
For i = 0 To wid - 2
For j = 0 To hgt - 2
Dim a,b,c As Integer
For x = 0 To 1
For y = 0 To 1
Dim cc As New Color
cc = bmp.GetPixel(i * 2 + x, j * 2 + y)
a += cc.a
b += cc.b
c += cc.c
Next
Next
a = a / 4
b = b / 4
c = c / 4
bmr.SetPixel(i, j, Color.FromArgb(a,b,c ))
a = 0 : b = 0 : c = 0
Next
Next
PictureBox1.Image = bmr
bmr.Save("test.jpg", Imaging.ImageFormat.Jpeg)
End If
End Sub
End Class
i want to show a form in the lower right of the taskbar but then when i use a dual monitor it just passes here is my code
Public Class BNotifyUI
Private Sub BNotifyUI_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Me.Visible = True
Dim x As Integer
Dim y As Integer
x = Screen.PrimaryScreen.WorkingArea.Width
y = Screen.PrimaryScreen.WorkingArea.Height = Me.Height
Me.ShowInTaskbar = False
Do Until x = Screen.PrimaryScreen.WorkingArea.Width = Me.Width
x = x - 1
Me.Location = New Point(x, y)
'text visible here
Loop
End Sub
Private Sub BNotifyUI_MouseClick(sender As Object, e As MouseEventArgs) Handles MyBase.MouseClick
'Me.Close()
End Sub
Solved, Thanks for the tips guys ^_^
Dim x As Integer
Dim y As Integer
x = Screen.PrimaryScreen.WorkingArea.Width
y = Screen.PrimaryScreen.WorkingArea.Height - Me.Height - 10
Me.ShowInTaskbar = False
Do Until x = Screen.PrimaryScreen.WorkingArea.Width - Me.Width - 20
x = x - 1
Me.Location = New Point(x, y)
'text visible here
Loop
I am collecting data from an Arduino and transmit on Visual Basic through the serial port. Now I wanted to plot a graph with time vs electrical energy (unit kWh) - time along the x-axis and electrical energy along the y-axis. Usually I am getting data of the current from Arduino.
Now I wanted to learn how to start plotting the graph. I need a simple example explaining plotting a graph for sample. I tried some example code. It seems they are not working.
How do I plot a graph time vs current read from serial? Once Visual Basic starts running, it should save data w.r.t system time and date.
Example available here
Current code
Imports System
Imports System.IO.Ports
Imports System.ComponentModel
Imports System.Threading
Imports System.Drawing
Public Class Form1
Dim myPort As Array
Dim Distance As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
PortComboBox.Items.AddRange(myPort)
BaudComboBox.Items.Add(9600)
BaudComboBox.Items.Add(19200)
BaudComboBox.Items.Add(38400)
BaudComboBox.Items.Add(57600)
BaudComboBox.Items.Add(115200)
ConnectButton.Enabled = True
DisconnectButton.Enabled = False
End Sub
Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectButton.Click
SerialPort1.PortName = PortComboBox.Text
SerialPort1.BaudRate = BaudComboBox.Text
SerialPort1.Open()
Timer1.Start()
'lblMessage.Text = PortComboBox.Text & " Connected."
ConnectButton.Enabled = False
DisconnectButton.Enabled = True
End Sub
Private Sub DisconnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisconnectButton.Click
SerialPort1.Close()
DisconnectButton.Enabled = False
ConnectButton.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
SerialPort1.Write("c")
System.Threading.Thread.Sleep(250)
Dim k As Double
Dim distance As String = SerialPort1.ReadLine()
k = CDbl(distance)
ListBoxSensor.Text = k
Catch ex As Exception
End Try
End Sub
Private Sub Relay_ON_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_ON.Click
SerialPort1.Write("1")
End Sub
Private Sub Relay_Off_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_Off.Click
SerialPort1.Write("0")
End Sub
End Class
Add a picturebox, a timer a button and a textbox:
PictureBox1 size = 768, 279
timer interval to 500
Private img As Bitmap
Private imgClone As Bitmap
Private widthInterval As Integer
'the distance from the left side of picturebox where x axis starts
Private leftPad As Integer = 50
'the distance from the down side of picturebox where x axis is
Private downPad As Integer = 30
'the distance from the up side of picturebox where y axis ends
Private upPad As Integer = 50
'the distance from the right side of picturebox where x axis ends
Private rightPad As Integer = 80
Private rn As New Random
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
drawBack()
Timer1.Enabled = True
End Sub
Private Sub drawBack()
Static count As Boolean = False
Dim g As Graphics
'number of values in x axis e.g 1, 2, 3, ... representing time
Dim numX As Integer = 23
'number of values in y axis representing KW/h
Dim numY As Integer = 5
Dim stringFormat As New StringFormat()
'arreys to hold the text for both axies
Dim arrayTextX(numX), arrayTextY(numY - 1) As String
Dim i As Integer
'the distance from the right side of picturebox where x axis stops
Dim rightPad As Integer = 80
Dim brush As Brush = New SolidBrush(Color.FromArgb(245, 255, 255))
Dim pen As Pen = New Pen(Color.FromArgb(212, 212, 212), 1)
Dim height, x, y As Integer
'Run once
If count = True Then
Return
End If
count = True
stringFormat.Alignment = StringAlignment.Center
img = New Bitmap(PictureBox1.Width, PictureBox1.Height)
imgClone = New Bitmap(PictureBox1.Width, PictureBox1.Height)
g = Graphics.FromImage(img)
g.SmoothingMode = SmoothingMode.AntiAlias
g.Clear(Color.White)
'the distance in x axis between each value
widthInterval = CInt((PictureBox1.Width - leftPad - rightPad) / (numX + 1))
'the distance in y axis between each value
height = CInt((PictureBox1.Height - upPad - downPad) / (numY + 1))
'fill arrays with text
For i = 0 To numX - 1
arrayTextX(i) = (i + 1).ToString
Next
For i = 0 To numY - 1
arrayTextY(i) = ((i + 1) * height).ToString
Next
'fill background of graph with color
g.FillRectangle(brush, New Rectangle(leftPad, upPad, PictureBox1.Width - leftPad - rightPad + 1, _
PictureBox1.Height - downPad - upPad))
'vertical lines
x = leftPad
For i = 0 To numX - 1
x += widthInterval
g.DrawLine(pen, x, PictureBox1.Height - downPad, x, upPad)
g.DrawString(arrayTextX(i), New Font("Arial", 8), Brushes.Black, _
New Rectangle(x - 10, PictureBox1.Height - downPad + 3, 20, 20), stringFormat)
Next
'horizontal lines
stringFormat.Alignment = StringAlignment.Far
y = PictureBox1.Height - downPad
For i = 0 To numY - 1
y -= height
g.DrawLine(pen, leftPad, y, PictureBox1.Width - rightPad, y)
g.DrawString(arrayTextY(i), New Font("Arial", 8), Brushes.Black, _
New Rectangle(0, y - 6, leftPad - 5, 20), stringFormat)
Next
g.DrawString("KW/Hour", New Font("Arial", 8, FontStyle.Bold), Brushes.Black, _
New PointF(5, 5))
g.DrawString("Time", New Font("Arial", 8, FontStyle.Bold), Brushes.Black, _
New PointF(PictureBox1.Width - 50, PictureBox1.Height - 20))
'draws x axis
g.DrawLine(Pens.Black, New Point(leftPad, PictureBox1.Height - downPad), _
New Point(PictureBox1.Width - rightPad, PictureBox1.Height - downPad))
'draws y axis
g.DrawLine(Pens.Black, New Point(leftPad, PictureBox1.Height - downPad), _
New Point(leftPad, upPad))
g.Dispose()
PictureBox1.Image = img
imgClone = CType(img.Clone, Bitmap)
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim value, x As Integer
Dim g As Graphics
Dim pntEnd As Point
Static pnt As Point = New Point(-1, -1)
Static staticX As Integer = -1
Dim hour As Integer = DateTime.Now.Hour
Dim minute As Integer = DateTime.Now.Minute
Dim second As Integer = DateTime.Now.Second
second = minute * 60 + second
x = leftPad + hour * widthInterval + CInt(CDbl(widthInterval - 1) * CDbl(second) / 3600.0R)
If pnt.X >= 0 Then
'checks if the new points x coordinate is the same as the previous and returns
If x <= staticX Then
Return
End If
End If
GetValue(value)
pntEnd = New Point(x, PictureBox1.Height - value - downPad)
g = Graphics.FromImage(img)
g.SmoothingMode = SmoothingMode.AntiAlias
If pnt.X < 0 Then
g.DrawLine(Pens.Red, pntEnd, pntEnd)
Else
g.DrawLine(Pens.Red, pnt, pntEnd)
End If
g.Dispose()
pnt = pntEnd
staticX = x
PictureBox1.Invalidate()
End Sub
Private Sub GetValue(ByRef value As Integer)
'here you can take the value from arduino.
value = rn.Next(0, PictureBox1.Height - downPad - upPad) 'random value
End Sub
When you press Button1 the graph starts.
Calculate width of graph (x axis)
width = PictureBox1.Width - leftPad - rightPad
this width is equivelant with 24h or 86400sec. So you should set the timer interval to
Timer1.Interval = CInt((86400 / width ) * 1000) 'in milliseconds
There is no need to be that because the tick function checks if the
new point is the same as the previous. So set timer interval to 1 second.
I have seen a loading animation for many Windows programs and apps, where a set of 5 dots start coming in to the centre of the screen from off the screen on the left, decelerating at an exponential rate but not stopping, and then move on uniformly right for about half a second, then start accelerating exponentially again and run off the screen on the right.
Is there a native, inbuilt way of using this in VB.NET? If not, is there a library or .dll I could use to emulate this effect? And if that's not possible, can anyone give an example of how to use e.Graphics or a similar method under the MyBase.Paint event to emulate it?
Please comment and ask me if you do not know which loading animation I am referring to. Here's a link to a very bad quality version of it (I don't want to use this one): https://www.dropbox.com/s/3vruzrkf8o3dzuy/294.GIF
The default ProgressBar doesn't support this for windows forms application.
Try the below code
Dim AreaHeight As Integer
Dim AreaWidth As Integer
Dim NumberOfItems As Integer
Dim DistanceBetweenItems As Integer
Dim ItemLength As Integer
Dim ItemX() As Decimal
Dim ItemIndex As Integer
Dim Bmp As Bitmap
Dim G1 As Graphics
Dim Stage As Integer
Dim dx1 As Integer
Dim dx2 As Decimal
Dim PictureBox1 As PictureBox
Dim WithEvents Timer1 As Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Size = New Size(235, 95)
Me.Text = "ProgressBar"
Me.Location = New Point(CInt((Screen.PrimaryScreen.WorkingArea.Width - Me.Width) / 2), CInt((Screen.PrimaryScreen.WorkingArea.Height - Me.Height) / 2))
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedToolWindow
PictureBox1 = New PictureBox
PictureBox1.Size = New Size(175, 15)
PictureBox1.Location = New Point(20, 20)
Me.Controls.Add(PictureBox1)
AreaHeight = PictureBox1.Height
AreaWidth = PictureBox1.Width
NumberOfItems = 4
DistanceBetweenItems = 5
ItemLength = 6
ItemIndex = 0
Stage = 1
dx1 = 10
dx2 = CDec(0.4)
ReDim ItemX(NumberOfItems - 1)
InitializePositions()
Bmp = New Bitmap(AreaWidth, AreaHeight)
G1 = Graphics.FromImage(Bmp)
PictureBox1.Image = Bmp
Timer1 = New Timer
Timer1.Interval = 30
Timer1.Enabled = True
End Sub
Private Sub AnimateProgressBar()
G1.Clear(Color.White)
If ItemIndex >= NumberOfItems Then
ItemIndex = 0
Stage += 1
If Stage = 3 Then
Stage = 1
InitializePositions()
End If
End If
Dim Distance As Integer = CInt(((AreaWidth / 2) * Stage) - (ItemLength * (ItemIndex + 1)) - (DistanceBetweenItems * ItemIndex) + (NumberOfItems * (ItemLength + DistanceBetweenItems)))
If ItemX(ItemIndex) + dx1 > Distance Then
ItemX(ItemIndex) = Distance
ItemIndex += 1
Else
ItemX(ItemIndex) += dx1
End If
Dim i As Integer
For i = 0 To NumberOfItems - 1
G1.FillEllipse(Brushes.Red, ItemX(i), CInt((AreaHeight - ItemLength) / 2), ItemLength, ItemLength)
G1.DrawEllipse(Pens.Black, ItemX(i), CInt((AreaHeight - ItemLength) / 2), ItemLength, ItemLength)
ItemX(i) += dx2
Next
Me.PictureBox1.Invalidate()
End Sub
Private Sub InitializePositions()
Dim i As Integer
For i = 0 To NumberOfItems - 1
ItemX(i) = -ItemLength * (i + 1) - (DistanceBetweenItems * i)
Next
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
AnimateProgressBar()
End Sub
If you tweak its parameters a little bit I think you will get the desired behavior.
I have an grayscale image, I have been a able to display a rectangle on the image to extract the ROI and compute the standard deviation and mean. However, when I'm moving the rectangle around, i notice I have the wrong values for the image, especially where the image is entirely black. At this area, i should be getting a zero for the mean and standard deviation. However, im obtaining a 0 for the mean and negative values for the standard deviation and other point of this black area the mean increases to the mean the same as light dominated areas. I have been struggling to come up with a solution. Are there any ideas to help. I'll be grateful. My code for the mousemove button and mean and standard deviation are posted below. Thanks.
Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Dim mean As Double = 0
Dim meancount As Integer = 0
Dim bmap As New Bitmap(400, 400)
bmap = PictureBox1.Image
Dim colorpixel As Color = bmap.GetPixel(e.X, e.Y)
' Dim pixels As Double = colorpixel.R + colorpixel.G + colorpixel.B
If e.Button = Windows.Forms.MouseButtons.Left AndAlso Rect.Contains(e.Location) Then
If (PictureBox1.Image Is Nothing) Or (PictureBox1.Height - (e.Y + SquareHeight) < 0) Or (PictureBox1.Width - (e.X + SquareWidth) < 0) Then
Else
Dim ROI As New Bitmap(400, 400)
Dim x As Integer = 0
Dim countx As Integer = 0
Dim county As Integer = 0
For i = e.X To (e.X + SquareWidth)
For j = (e.Y + x) To (e.Y + SquareHeight)
Dim pixelcolor As Color = bmap.GetPixel(i, j)
ROI.SetPixel(countx, county, pixelcolor)
mean = mean + pixelcolor.R + pixelcolor.G + pixelcolor.B
county += 1
meancount += 1
Next
county = 0
countx += 1
x = x + 1
Next
mean = mean / meancount
Dim SD = mean - 75
Dim area As Integer = (SquareHeight * SquareWidth)
Dim anotherForm As Form2
anotherForm = New Form2(mean, SD, area, 34)
anotherForm.Show()
End If
End If
' Catch ex As Exception
' MessageBox.Show(ex.Message())
' End Try
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
Rect.X = e.X + x
Rect.Y = e.Y + y
Rect.Width = SquareWidth
Rect.Height = SquareHeight
' Label1.Text = "XRect: " + Rect.X.ToString() + " YRect: " + Rect.Y.ToString() + " Xmouse " + e.X.ToString() + " Ymouse " + e.Y.ToString()
PictureBox1.Refresh()
End Sub
Private Sub PictureBox1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.DrawRectangle(Pens.Red, Rect)
End Sub
Private Function StandardDeviation(ByVal image As Bitmap, ByVal mean As Double, ByVal meancount As Integer) As Double
Dim SD(SquareHeight * SquareWidth) As Double
Dim count As Integer = 0
For i = 0 To SquareWidth
For j = 0 To SquareHeight
Dim pixelcolor As Color = image.GetPixel(i, j)
SD(count) = Double.Parse(pixelcolor.R) + Double.Parse(pixelcolor.G) + Double.Parse(pixelcolor.B) - mean
count += 1
Next
Next
Dim SDsum As Double = 0
For i = 0 To count
SDsum = SDsum + SD(i)
Next
SDsum = SDsum / (SquareHeight * SquareWidth)
SDsum = ((SDsum) ^ (1 / 2))
Return SDsum
End Function
Private Sub PictureBox1_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseClick
Dim P As Point = e.Location
P = New Point
End Sub
You should calc mean like
mean = mean / (meancount * 3) (there is 3 colors added) and it is better to calc running mean instead of summing all and divide later. I guess there can be more math errors.