Converting RGB to Gray scale? - vb.net

I am new to Visual Basic, I've done image processing in matlab in the past. But require Image Processing in Visual Basic as of this moment. Okay, I've been able to display the image and read up on converting to grayscale. However my image is in jpeg format and i keep running into the Bitmap function for only bmp images in several grayscale converter tutorials and my code keep producing errors for attempts in manipulation for JPEG format. How do i read in the jpeg and perform the grayscale manipulation. Here is the code.
Public Class Form1
Private Sub showButton_Click(sender As System.Object, e As System.EventArgs) Handles showButton.Click
' Show the Open File dialog. If the user clicks OK, load the
' picture that the user chose.
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
PictureBox1.Load(OpenFileDialog1.FileName)
End If
End Sub
Private Sub GrayImageButton_Click(sender As System.Object, e As System.EventArgs) Handles GrayImageButton.Click
Dim bm As New jpeg(PictureBox1.Image)
Dim X As Integer
Dim Y As Integer
Dim clr As Integer
For X = 0 To bm.Width - 1
For Y = 0 To bm.Height - 1
clr = (CInt(bm.GetPixel(X, Y).R) + _
bm.GetPixel(X, Y).G + _
bm.GetPixel(X, Y).B) \ 3
bm.SetPixel(X, Y, Color.FromArgb(clr, clr, clr))
Next Y
Next X
PictureBox1.Image = bm
End Sub
The error I'm recieving is
Error1 : Value of type 'WindowsApplication1.jpeg' cannot be converted to 'System.Drawing.Image'.
When I implement this with a bmp image it works perfectly, but not with a jpeg. I will be grateful for any help with this issue. Thanks

Just change:
Dim bm As New jpeg(PictureBox1.Image)
To:
Dim bm As New Bitmap(PictureBox1.Image)
It would be faster, though, to use a ColorMatrix like this:
Private Sub GrayImageButton_Click(sender As System.Object, e As System.EventArgs) Handles GrayImageButton.Click
Dim grayscale As New Imaging.ColorMatrix(New Single()() _
{ _
New Single() {0.299, 0.299, 0.299, 0, 0}, _
New Single() {0.587, 0.587, 0.587, 0, 0}, _
New Single() {0.114, 0.114, 0.114, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {0, 0, 0, 0, 1} _
})
Dim bmp As New Bitmap(PictureBox1.Image)
Dim imgattr As New Imaging.ImageAttributes()
imgattr.SetColorMatrix(grayscale)
Using g As Graphics = Graphics.FromImage(bmp)
g.DrawImage(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height), _
0, 0, bmp.Width, bmp.Height, _
GraphicsUnit.Pixel, imgattr)
End Using
PictureBox1.Image = bmp
End Sub

Where is jpeg defined? Is that a VB.Net Library you are using? Or have you written this object yourself?
.Net has some built-in Jpeg utilities, you may want to check this out:
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.jpegbitmapdecoder.aspx
With this you should be able to access the pixels, from there your background in color manipulation should allow you to use this to do exactly what you are looking to do.

I would suggest looking at an imaging library like AForge or OpenCV. They have lots of useful functions built-in (several different RGB-to-Grayscale algorithms, for example). OpenCV is written in C++ so it's probably going to be faster than anything you can write in VB. I'm not sure about AForge, but I think it is written in C#.

There is no such type as jpeg in vb.net so the line:
Dim bm As New jpeg(PictureBox1.Image)
should be replaced by
Dim bm as Bitmap = New Bitmap(PictureBox1.image)

Here is a good code
Sub BlackAndWhite()
Dim x As Integer
Dim y As Integer
Dim red As Byte
Dim green As Byte
Dim blue As Byte
For x = 0 To I.Width - 1
For y = 0 To I.Height - 1
red = I.GetPixel(x, y).R
green = I.GetPixel(x, y).G
blue = I.GetPixel(x, y).B
I.SetPixel(x, y, Color.FromArgb(blue, blue, blue))
Next
Next
PictureBox1.Image = I
End Sub

Related

How to detect graphic edges and only save that portion

I have a PictureBox, which I am using as a "Signature pad". The size is 475,175...If the user signs in a small area, I would like to only save the portion that has a signature mark. I am not sure where to begin. Any help would greatly be appreciated.
Private Sub btnSaveSignature_Click(sender As Object, e As EventArgs) Handles btnSaveSignature.Click
Dim signatureFileName = txtSignatureFileName.Text.Trim()
Dim signaturePath As String = Path.Combine(Application.StartupPath, txtSignatureFileName.Text & ".bmp")
If String.IsNullOrEmpty(signatureFileName) Then Return
If currentCurve < 0 OrElse signatureObject(currentCurve).Count = 0 Then Return
Using imgSignature As Bitmap = New Bitmap(pBoxSignature.Width, pBoxSignature.Height, PixelFormat.Format32bppRgb)
Using g As Graphics = Graphics.FromImage(imgSignature)
''BMPs require a White background. This line provide that.
g.FillRectangle(Brsh, 0, 0, pBoxSignature.Width, pBoxSignature.Height)
Call DrawSignature(g)
End Using
pBoxSignature.SizeMode = PictureBoxSizeMode.AutoSize
pBoxSavedSignature.SizeMode = PictureBoxSizeMode.AutoSize
imgSignature.Save(signaturePath, ImageFormat.Bmp)
pBoxSavedSignature.Image = New Bitmap(imgSignature)
End Using
End Sub
The above code is my Save to BMP routine. I would imagine any solution would need to go in this section.

VB.NET Dispose Bitmap in RAM wont work

first of all i am relative new to Visual Basic.NET and i stuck on an problem here.
I started to code a screen2gif recorder. In main purpose it works. But if i record more than 15 to 20 seconds my ram overloads and exceed the 3,5 Gb limit for x32bit applications. The problem is that the bitmaps i create stack over and over.
Private Function getBitmap(ByVal pCtrl As Control) As Bitmap
Dim myBmp As Bitmap
If myBmp IsNot Nothing Then
myBmp.Dispose()
End If
myBmp = New Bitmap(pCtrl.Width, pCtrl.Height)
Dim g As Graphics = Graphics.FromImage(myBmp)
Dim p As New Point(pCtrl.Parent.Width - pCtrl.Parent.ClientRectangle.Width - 4, pCtrl.Parent.Height - pCtrl.Parent.ClientRectangle.Height - 4)
g.CopyFromScreen(pCtrl.Parent.Location + pCtrl.Location + p, Point.Empty, myBmp.Size)
Dim LocalMousePosition As Point
LocalMousePosition = panelTranspacrency.PointToClient(Cursor.Position)
Cursor.Draw(g, New Rectangle(New Point(LocalMousePosition.X, LocalMousePosition.Y), Cursor.Size))
Return myBmp
myBmp.Dispose()
g.Dispose()
End Function
Private Sub tmrWork_Tick(sender As Object, e As EventArgs) Handles tmrWork.Tick
counter += 1
Dim bm As Bitmap
bm = getBitmap(Me.panelTranspacrency)
bm.Save(My.Settings.outputpath & "\temp\" & counter & ".png", Drawing.Imaging.ImageFormat.Png)
bm.Dispose()
End Sub
So this is my code to create the bitmaps and save them to disk.
I mention that i used the .Dispose command but the ram wont free.
Please take a look and give me a hint. Thanks in advance.
Change
Dim g As Graphics = Graphics.FromImage(myBmp)
to
Using g As Graphics = Graphics.FromImage(myBmp)
and put End Using after your Return myBmp. And you should do the same with
Using bm As Bitmap = getBitmap(Me.panelTranspacrency)
And remove all your explicit .Dispose calls as well.
Docs
https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/using-statement

vb 2015 GDI+ bitmap placement

I've had little luck trying to find the answer to this either on stackoverflow specifically, or on the internet in general.
I have a form in a vb 2015 Windows Forms project.
On that form, I've placed six controls: four textboxes, a panel, and a button.
When I click the button, it generates a bitmap, like so:
Private Sub btnSetLeft_Click(sender As Object, e As EventArgs) Handles btnSetLeft.Click
Dim R As Integer = CInt(txtRedLeft.Text)
Dim G As Integer = CInt(txtGreenLeft.Text)
Dim B As Integer = CInt(txtBlueLeft.Text)
Dim A As Integer = CInt(txtAlphaLeft.Text)
gcL = Color.FromArgb(A, R, G, B)
Using bm As Bitmap = New Bitmap(9, 9)
Using gBM As Graphics = Graphics.FromImage(bm)
Using br As SolidBrush = New SolidBrush(gcL)
gBM.FillRectangle(br, New Rectangle(0, 0, 8, 8))
End Using
End Using
End Using
End Sub
But, after building the bitmap, I want the button to place the bitmap on the panel and then repaint the panel, thus displaying the new bitmap.
How do I do that?
It's not too hard (I simplified your example):
Dim gcL As Color = Color.Blue
Using bm As New Bitmap(9, 9)
Using gBM As Graphics = Graphics.FromImage(bm)
Using br As New SolidBrush(gcL)
gBM.FillRectangle(br, New Rectangle(0, 0, 8, 8))
End Using
End Using
panel1.BackgroundImage = bm
panel1.BackgroundImageLayout = ImageLayout.Tile
panel1.Update()
End Using

Obtaing the ROI in Visual basic errors in code after conversion from C

I've been working on obtaining the ROI of an image, I'm trying to get a square shaped box that will hoover around the region an be able to click and get the standard deviation. I'm familiar with c so i used the c to VB converter, but im getting errors that the statement is not valid in namespace. Everything seems to compatible to VB code. I will be grateful for any suggestions on this matter. Thanks
Private Function DrawRoi(Image As Bitmap, rect As RectangleF) As oid
Dim roi As New Rectangle()
roi.X = CInt(CSng(Image.Width) * rect.X)
roi.Y = CInt(CSng(Image.Height) * rect.Y)
roi.Width = CInt(CSng(Image.Width) * rect.Width)
roi.Height = CInt(CSng(Image.Height) * rect.Height)
Dim timer As New Stopwatch()
timer.Start()
' graphics manipulation takes about 240ms on 1080p image
Using roiMaskImage As Bitmap = CreateRoiMaskImage(ImageWithRoi.Width, ImageWithRoi.Height, roi)
Using g As Graphics = Graphics.FromImage(ImageWithRoi)
g.DrawImage(Image, 0, 0)
g.DrawImage(roiMaskImage, 0, 0)
Dim borderPen As Pen = CreateRoiBorderPen(ImageWithRoi)
g.DrawRectangle(borderPen, roi)
End Using
End Using
Debug.WriteLine("roi graphics: {0}ms", timer.ElapsedMilliseconds)
Me.imagePictureBox.Image = ImageWithRoi
End Function
Private Function CreateRoiMaskImage(width As Integer, height As Integer, roi As Rectangle) As Bitmap
Dim image As New Bitmap(width, height, PixelFormat.Format32bppArgb)
Using g As Graphics = Graphics.FromImage(image)
Dim dimBrush As New SolidBrush(Color.FromArgb(64, 0, 0, 0))
g.FillRectangle(dimBrush, 0, 0, width, height)
Dim roiBrush As New SolidBrush(Color.Red)
g.FillRectangle(roiBrush, roi)
image.MakeTransparent(Color.Red)
Return image
End Using
End Function

Live text reader with highlighting in VB.net

I have a program which writes to a .log file as it is installing software.
Some of the lines will contain either WARNING or FAILED.
What I would like, is a window in my program which will read the .log file and display the content into this window as it is being written too. Any lines which contain WARNING or FAILED in them are highlighted yellow/red.
Does anyone know how to do this?
Create a FORM (I used VB 2010) and add this code.
it will write 3 lines on the form in 2 colours.
It might get you on your way. Ask MSDN help for each function that is new to you.
Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim chRs(0) As CharacterRange
Dim sbRs(0) As SolidBrush
Dim flRs(0) As SolidBrush
Dim blueBrush As New SolidBrush(Color.Blue)
Dim whiteBrush As New SolidBrush(Color.White)
Dim redBrush As New SolidBrush(Color.Red)
Dim EditFont As New Font("Courier New", 9)
Dim stringFormat As New StringFormat
Dim aRectangle As Rectangle
Dim RectHeight As Integer = 20
For i = 1 To 3
Dim txt As String = "a string " & CStr(i)
If i = 2 Then
sbRs(0) = blueBrush
Else
sbRs(0) = redBrush
End If
flRs(0) = whiteBrush
chRs(0) = New CharacterRange(0, txt.Length())
Dim chRsa As Array = Array.CreateInstance(GetType(CharacterRange), 1)
Array.Copy(chRs, 0, chRsa, 0, 1)
aRectangle = New Rectangle(0, CInt((i - 1) * RectHeight), ClientRectangle.Size.Width, RectHeight) ' x, y, w, h
stringFormat.SetMeasurableCharacterRanges(chRsa)
Dim stringRegions As Array = Array.CreateInstance(GetType([Region]), 1)
stringRegions = e.Graphics.MeasureCharacterRanges(txt, EditFont, aRectangle, stringFormat)
Dim measureRect1 As RectangleF = stringRegions(0).GetBounds(e.Graphics)
Dim g As Graphics = e.Graphics
g.FillRectangle(flRs(0), measureRect1)
g.DrawString(txt.Substring(chRs(0).First, chRs(0).Length), EditFont, sbRs(0), CSng(measureRect1.X), CSng(measureRect1.Y))
Next
End Sub