Improve Performance With GDI+ - vb.net

As a challenge, I am planning to make a game purely in Visual Studio (using Visual Basic) but in the past, I have noted that GDI+ is not the best rendering tool, but for what it is, it's all right.
What settings should I use and not use when working with GDI+? Here are my assumptions:
InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor It would make sense that this option renders the fastest.
PixelOffsetMode = Drawing2D.PixelOffsetMode.Half This seems like it must be used with NearestNeighbor.
CompositingQuality = ? I am not sure about this one.
CompositingMode = ? Again, I can't tell.
SmoothingMode = Drawing2D.SmoothingMode.None Specifying no smoothing mode would probably run the fastest.
SetClip(ClientRectangle) It would make sense to set this as the clip so the graphics would not draw outside of the form or control.
My next point: I've noticed that adding all the graphics code always works the fastest in Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Is there any benefit to doing something like this inside that void: (Creating a temporary bitmap and drawing it onto the screen.)
Using B As New Bitmap(ClientSize.Width, ClientSize.Height, Imaging.PixelFormat.Format32bppPArgb)
Using G As Graphics = Graphics.FromImage(B)
' Draw objects onto the bitmap.
End Using
e.Graphics.DrawImage(B, 0, 0)
End Using
I ask this because I noticed that when creating a bitmap, you can specify a Imaging.PixelFormat. Is there one type of format that renders faster than the rest?
Thank you all in advance for the help.
~Nic

Related

Saving Database issue

So basically, I believe I am using the correct code yet the database will still not update. It will work for the current session, however, when I stop and restart the program, it appears that the data has not been updated in the database.
The really interesting part is that I am using the same method to update the database elsewhere, which when used and session restarted, the database has been updated.
p.s. I also have the same adapters and binding sources set up etc on both forms
I am so confused, help pls
Code that I believe is correct but is not working: (updating on another form so I have one place where all forms update hence FRMMain. etc)
Private Sub btnConfirm_Click(sender As Object, e As EventArgs) Handles btnConfirm.Click
Dim CurrentPoints As Integer
Dim UpdatedPoints As Integer
CurrentPoints = FRMMain.MyDBDataSet.Tables("TBLPupil").Rows(looopcount)(15)
UpdatedPoints = CurrentPoints + stfPoints
FRMMain.MyDBDataSet.Tables("TBLPupil").Rows(looopcount)(15) = UpdatedPoints
FRMMain.TBLPupilTableAdapter.Update(MyDBDataSet.TBLPupil)
FRMMain.TBLPupilTableAdapter.Fill(MyDBDataSet.TBLPupil)
End Sub
Code that I am using in another form that that DOES work:
Private Sub BtnYes_Click(sender As Object, e As EventArgs) Handles BtnYes.Click
Dim Points As Integer = FRMPupil.Pointss
Dim Cost As Integer = FRMPupil.RewardCost
Points = Points - Cost
FRMPupil.LePoints = Points
MyDBDataSet.Tables("TBLPupil").Rows(FRMLogin.DBLocation)(15) = Points
FRMMain.TBLPupilTableAdapter.Update(MyDBDataSet.TBLPupil)
FRMMain.TBLPupilTableAdapter.Fill(MyDBDataSet.TBLPupil)
Me.Hide()
End Sub
My code is correct but is not working.
No, if it is not working, then it is not correct!
There are different things you can do: DRY, Dont Repeat Yourself. You are repeating the code for updating points at several places in your code. This is error prone. Write it once and re-use it, e.g. by applying the the Repository Pattern. It makes it easier to detect errors and correct them. It allows you to re-use code that has already been tested in other scenarios (on another form).
Debug, debug, debug. Place breakpoints in the not working methods and see what happens. Do all the variables have the expected values? E.g., does looopcount have the same value as FRMLogin.DBLocation? There must be a difference somewhere. See: Navigating through Code with the Debugger or the more recent article Debug your Hello World application with Visual Studio 2017.

Is it feasable to create a program that can select an image out of a number of images given. e.g. a spiral galaxy versus an ellpictcal one

I want to create an algorithim that can distinguish between two (or more) images, and find the one I want it to. For example, a program that takes two images, a spiral and elliptical galaxy image and selects the spiral one by noticing differences in the two. I'd like to do this is VB.NET.
I'm not a beginner, can this be done in a reasonable amount of time? What kind of libraries will I need and is there anything else?
Only thing that comes close to what you are asking as below, more complex comparison would require some kind of machine learning network.
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
PictureBox1.Image = Bitmap.FromFile("C:\Users\Public\Pictures\Sample
Pictures\Tulips.jpg")
PictureBox2.Image = Bitmap.FromFile("C:\Users\Public\Pictures\Sample
Pictures\Tulips.jpg")
Dim a As Boolean = AreSameImage(PictureBox1.Image, PictureBox2.Image)
If a Then
MsgBox("Identical image")
Else
MsgBox("Different images")
End If
End Sub
Public Function AreSameImage(ByVal I1 As Image, ByVal I2 As Image) As Boolean
Dim BM1 As Bitmap = I1
Dim BM2 As Bitmap = I2
For X = 0 To BM1.Width - 1
For y = 0 To BM2.Height - 1
If BM1.GetPixel(X, y) <> BM2.GetPixel(X, y) Then
Return False
End If
Next
Next
Return True
End Function
End Class
IMHO, image processing (signal processing in general) is one of the most difficult things to program. What our brain does so easily, distinguishing and classifying sounds and images, is awfully difficult for a computer.
If you want to implement an algorithm that does something as "simple" as telling apart galaxy shapes, besides programming skills you'll need to know some stuff about image processing and algorithms, or either be very familiar with a specific image processing library. For this second option, there are a lot of image processing libraries for .NET, you have multiple choices, you can just Google them, but still you'll have to learn the basics of image processing, and then learn to work with that library.
So, responding to your question: "can this be done in a reasonable amount of time?". If you haven't done any image processing programming before, I would say no.

No result using BITMAP

Here's a code snippet:
Dim BMf As Bitmap
BMf = New Bitmap(PicBox.Width, PicBox.Height)
Call FourierPlot(PlotHeight, PlotWidth, RPMArray, CoefArray, Count, 2, BMf)
Me.PicBox.Image = BMf
BMf.Dispose()
within the subroutine is code such as:
Dim myGraphics As Graphics = Graphics.FromImage(BMf)
Dim myPen As New Pen(colr)
....
myGraphics.DrawLine(myPen, lastx, lasty, temp1, temp2)
....
myPen.Dispose()
myGraphics.Dispose()
The displayed PicBox consists of a boundary rectangle with lines draw from opposing corners (what I presume is an "error image.)
Any suggestions (hopefully VERY simple ones) as to what I'm doing wrong?
You shouldn't call BMf.Dispose(), because the image is going to be used by the picture box.
Update:
OK, small update because this seems to be confusing to the OP and others.
When you say Me.PicBox.Image = BMf you set a reference to the bitmap. Both BMf and PicBox.Image now point to the same object. Thus, you should not dispose it, because then it can't be used anymore. Again - this is not a copy, this is same object.
And about leaks. Removing this line does not cause any memory or other leaks. .NET is managing this for you. As soon as the bitmap will not be needed (which means nobody has a reference to it = your picture box will load another image), it will be unneeded and disposed at the next run of the garbage collector. This is automatic.
You might want to disposed it manually if you really need to care about resource, for example if you would invoked your code and create new bitmaps often, many times. But in this case you probably would be better off forcing garbage collector to run in places, where you can cause some delay to the user. You can do this like this:
GC.Collect()

Using GetWindowDC for drawing

I'm having difficulties in using Win API GetWindowDC to get a valid hDC for drawing.
I'm using vb.net 2013, and I tried to bitblt images to a form, draw string, draw rectangle, and nothing.
I'm running in Win7 all the tests.
Do I have to disable aero with DWM functions, is it a handle trick, or what is? I already posted a "draw in titlebar vb.net 2013" question that had no answer, where I have some code used, but right now, I just need a working example to start. All help is appreciated.
But here goes some more code that doesn't work either.
Select Case m.Msg
Case WinAPI.Win32Messages.WM_NCPAINT
Dim hDC As IntPtr = WinAPI.GetWindowDC(m.HWnd)
Dim g As Graphics = Graphics.FromHwnd(hDC)
g.DrawString("TESTE", New Font("ARIAL", 16), New SolidBrush(Color.Black), 5, 5)
g.Dispose()
WinAPI.ReleaseDC(m.HWnd, hDC)
The error is OutOfMemory, and nothing gets drawn anywhere, even with tests done to clientarea.
It's a simple purpose. Getting to draw in all the areas of a form, and from that on, I'll handle the drawing.
Well, thanks at least for the help on correctly editing. About the Graphics.FromHDC, yes, I tried it.
But here goes some more code that doesn't work either.
Select Case m.Msg
Case WinAPI.Win32Messages.WM_NCPAINT
Dim hDC As IntPtr = WinAPI.GetWindowDC(m.HWnd)
Dim g As Graphics = Graphics.FromHwnd(hDC)
g.DrawString("TESTE", New Font("ARIAL", 16), New SolidBrush(Color.Black), 5, 5)
g.Dispose()
WinAPI.ReleaseDC(m.HWnd, hDC)
The error is OutOfMemory, and nothing gets drawn anywhere, even with tests done to clientarea.
It's a simple purpose. Getting to draw in all the areas of a form, and from that on, I'll handle the drawing. And too bad for the negative votes. Doesn't help, cause if people where fast on the negative voting...try to be as fast on reading all of what's placed in a question, and finding out that it is not just "gimme gimme codez" - the other referenced question has code.
People that know a lot forget that once you where like me, and didn't know a lot about the subject...might not even know how to ask the right questions...
Thanks for the help, if someone can provide it.
Graphics.FromHwnd() takes a window handle, not a DC (the clue is in the name). Try Graphics.FromHdc() instead.

OutofMemory Exception on new Bitmap()

I have to draw something on a Image wich is captured by the Camera. This works on many Devices, but sometimes the RAM is too small or the pictures too big and the function crashed with a OutOfMemory Exception.
How am I able to:
a) optimize the code to prevent this Exceptions
b) Handle this Exceptions (making pictures smaller, free Ram etc.
here is the code:
Dim from_bmp As Bitmap
Dim bmp As Bitmap
from_bmp = New Bitmap(picname)
'I also tryed this with a function which is creating the Bitmap from Filestream
'I also tryed this with the OpenNETCF.Drawing.Imaging.IImage
'If the Original Pictiure is too big, the function will crash here.
bmp = New Bitmap(from_bmp.Width, from_bmp.Height + stampheight)
'now I Create a bitmap which is higher than the original, in order to write the stamp beneth the picture
Dim font As New System.Drawing.Font("Arial", 30, FontStyle.Regular)
gr = Graphics.FromImage(bmp)
gr.DrawImage(from_bmp, 0, 0)
from_bmp.Dispose()
'here I draw somethin in the Bitmap
bmp.Save(deststring, System.Drawing.Imaging.ImageFormat.Jpeg)
gr.Dispose()
bmp.Dispose()
I'd likely use a "using" pattern for your Bitmaps. Also, be aware that an OOM on Bitmap creation can often be overcome by simply trying again (here's a diatribe as to why). My bet is that the GC Heap is too full and a second request, especially after a collection, would succeed.
I'd go through the rest of the code (that not shown) and make sure that all other graphics objects are getting properly Disposed - the CF doesn't handle auto clean-up of the native resources of graphic objects very well and often needs a bit of help (again, see the above link).