My image in a picture box is not rotating on keypressed - vb.net

I am doing a car parking game.i am using the arrow keys to move it,but when the down key is pressed,the picture box does not move down.Also ,when the right or up keys are pressed,the picture box does not stop.I want also to rotate the car while moving right or left.I tried but was not able.
Private Sub Timerdiagonalright_Tick(sender As Object, e As EventArgs) Handles Timerdiagonalright.Tick
RotateImage(pbcar1.Image, 20)
End Sub
Private Function RotateImage(img As Image, angle As Single) As Bitmap
' the calling code is responsible for (and must)
' disposing of the bitmap returned
Dim retBMP As New Bitmap(img.Width, img.Height)
retBMP.SetResolution(img.HorizontalResolution, img.VerticalResolution)
Using g = Graphics.FromImage(retBMP)
' rotate aroung the center of the image
g.TranslateTransform(img.Width \ 2, img.Height \ 2)
'rotate
g.RotateTransform(angle)
g.TranslateTransform(-img.Width \ 2, -img.Height \ 2)
'draw image to the bitmap
g.DrawImage(img, New PointF(0, 0))
Return retBMP
End Using
End Function

If the image is already loaded to your PictureBox, your can use
PictureBox.Image.RotateFlip(RotateFlipType)
to rotate your image.
Please note that this is not an efficient way to do animated graphics; to improve performance a little when moving controls, consider reading on SuspendLayout / ResumeLayout and BeginUpdate / EndUpdate.

Related

Fill a Rectangular with an inflating Circle without crossing its borders (Ripple)

I have a control surface (my custom control) and a drawed rectangular smaller than the whole surface. Now I need to draw a circle (FillEllipse) within this rectangular and the circle must not overdraw the rectangular borders.
I made a ButtonStrip like this one know from Angular:
https://material.angular.io/components/button-toggle/overview
And want to create such ripples:
https://material.angular.io/components/ripple/examples
It is almost perfect. I would like to make such an animation. The filling progress is not a problem, but the fact, that I dont use kinda "child control buttons" in my ButtonStrip and therefore no "real" borders, I struggle with the not"over"drawing the borders of my clicked button.
And no, I will not use child buttons as controls to put into my strip. I dont want this control in control control. I am drawing the buttons and use the rectangulars as "address" for my events like Hover/Click/Clicked etc.
Here is an example of my ButtonStrip (Month is hovered). Day is clicked.
Every Button (in a List or Dictionary) has its own rectangular which is pre calculated:
Dim InnerWidth As Integer = If(_IOSwitchVisible = True,
(Me.Width - _IOSwitchWidth) \ Buttons.Count,
Me.Width \ Buttons.Count)
If InnerWidth = 0 Then Return
For Each b In Buttons.Values
b.Rect = New Rectangle(CurrLeft, 0, InnerWidth, Me.Height)
VerticalLinePos.Add(CurrLeft)
CurrLeft += InnerWidth
Next
This is only a part of the code.
And here is a snippet how I draw a clicked button (either hovered or not)
'Clicked
For Each btn In Buttons.Values.ToList.Where(Function(x) x.Clicked = True)
If _HoveredElement IsNot Nothing AndAlso _HoveredElement.Rect = btn.Rect Then
'If the button is already clicked
e.Graphics.FillRectangle(New SolidBrush(ClickedHoveredColor), btn.Rect)
Else
'Otherwise draw clicked color
e.Graphics.FillRectangle(New SolidBrush(ClickedColor), btn.Rect)
End If
Next
Does someone got an idea how to fill one of these buttons with a circle which must not overdraw to its neighbour buttons?
Edit: As soon as I (or you) found out how, I will include a loop to inflate the circle to animate a filling progress.
Thanks to Jimi I got it working with his Clip hint:
(The yellow circle is from ScreenToGif)
Private Sub AnimateRipple(G As Graphics, C As Color, R As Rectangle)
Dim ClipRegion As New Region(R)
G.SetClip(ClipRegion, Drawing2D.CombineMode.Replace)
Dim EllipseRect As Rectangle = R
EllipseRect.Width = 1
EllipseRect.Height = 1
EllipseRect.Y = R.Height \ 2
EllipseRect.X += R.Width \ 2
EllipseRect.Inflate(InflateValue, InflateValue)
Dim RippleBrush As SolidBrush = New SolidBrush(C)
G.FillEllipse(RippleBrush, EllipseRect)
G.ResetClip()
RippleBrush.Dispose()
End Sub

VB.Net Custom Bitmap

Its a bit complicated and I will try my best to explain what I want to achieve.
I've already worked a bit with bitmaps and copy from screen functions.
This all worked very well. But these bitmaps are always rectangles and I would like to use my own bitmap if possible.
As an example:
Somewhere at position x, y on my screen is a map
This map has several paths and junctions.
There are also houses and things that don't interest me, I only focus on the paths in between.
Now I want to scan this map for Argb Pixels using a bitmap and Copy from screen function. I have already done this and it works great, but instead of only scanning the paths for pixels, the whole map is scanned for pixels. But I only want these paths to be scanned.
I have this map as a template and could make a screenshot of it. Can I now import this map into Photoshop, color the houses and everything that I don't need black and make the paths transparent and import them as bitmap so that the Copy From Screen function only scans the paths or is that even possible? I haven't found anything for vb.net if someone could lead me in a right direction I would be very thankful :)
This is the code I got so far - simple pixelsearch function:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim xd3 = Color.FromArgb(255, 100, 100, 100) 'Searching for this color on the screen
Dim b As New Bitmap(2210, 1100) 'Position of Bitmap
Dim g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(b)
g.CopyFromScreen(Me.Left, Me.Top, 0, 0, b.Size) 'Searching on Screen
For i = 0 To (Me.Width - 0) 'searching each pixel
For j = 0 To (Me.Height - 0) 'searching each pixel
If b.GetPixel(i, j) = xd3 Then 'If pixel has same color that im searching for it will show a messagebox true
MessageBox.Show("true")
End If
Next
Next
End Sub

Disappearing Picturebox images [duplicate]

This question already has answers here:
Drawing Graphics Disappear in VB.net
(4 answers)
Closed 5 years ago.
I was successful in loading an image from a file into a picturebox in visual basic. Or so i thought. I had a msgbox in the code and the picture showed up in the picturebox. take the msgbox out and no picture. Any Ideas? Thanks
Private Sub DrawImageinSquarePanel(Panelname As PictureBox, ImageFile As String)
g = Panelname.CreateGraphics() 'creates new graphics element in panel
Dim newImage As Image = Image.FromFile(ImageFile) ' Create image.
Dim SquareDim As Integer 'Size of longest dimension in source image
If newImage.Width > newImage.Height Then
SquareDim = newImage.Width
Else
SquareDim = newImage.Height
End If
MsgBox(Panelname.Width & " " & Panelname.Height) 'the magic msgbox!!
' scale factor
Dim imageAttr As New ImageAttributes
imageAttr.SetGamma(Panelname.Width / SquareDim)
Dim ScaleFactor As Single = Panelname.Width / SquareDim
' Create rectangle for source and destination image.
Dim srcRect As New Rectangle(0, 0, newImage.Width, newImage.Height)
Dim destRect As New Rectangle((Panelname.Width - newImage.Width * ScaleFactor) / 2, (Panelname.Height - newImage.Height * ScaleFactor) / 2, newImage.Width * ScaleFactor, newImage.Height * ScaleFactor)
Dim units As GraphicsUnit = GraphicsUnit.Pixel
' Draw image to screen.
g.DrawImage(newImage, destRect, srcRect, units)
End Sub
Your title says "Picturebox" but there's no PictureBox there at all. If you want to display an Image in a PictureBox then assign the Image object to the Image property of that PictureBox.
Don't use GDI+ to draw it on a Panel and, if you ever do use GDI+ to draw, NEVER call CreateGraphics. Always draw on a control in its Paint event handler. The reason that your drawing disappears is that all drawing is erased on every Paint event. By doing your drawing in the Paint event handler, you ensure that it gets reinstated each time.
If you want to modify the image before displaying it then what you should do is create a new Bitmap object, use GDI+ to draw the modified image onto that and then assign that to the Image property of the PictureBox, e.g.
Using originalImage = Image.FromFile(filePath)
Dim newImage As New Bitmap(originalImage.Width, originalImage.Height)
Using g = Graphics.FromImage(newImage)
g.DrawImage(originalImage, Point.Empty)
End Using
'Dispose the existing image if there is one.
PictureBox1.Image?.Dispose()
PictureBox1.Image = newImage
End Using

slicing a jpg with vb.net

since i do not have any image editing software, i am going to use vb.net to slice an image horizontally. can someone help me get started please?
In the code below you first load the image, then create a new image with the new width and height, grab the Graphics object from it and finally draw the old image onto the new image. We draw the old image onto the new image using the old image's dimensions but since the new image is smaller the rest will be off of the canvas.
Private Shared Sub CropImage(ByVal inputImagePath As String, ByVal outputImagePath As String, ByVal newHeight As Integer)
Using oldImage = System.Drawing.Image.FromFile(inputImagePath)
Using NewImage As New System.Drawing.Bitmap(oldImage.Width, newHeight)
Using G = Graphics.FromImage(NewImage)
G.DrawImage(oldImage, 0, 0, oldImage.Width, oldImage.Height)
NewImage.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Jpeg)
End Using
End Using
End Using
End Sub

DataGridViewButtonColumn icon

i am using vb.net 2.0 and i would like to set an icon or image in a DataGridViewButtonColumn. I know the class has no member for it. Anyone has an idea?
Best answer is from http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/b0dfb55c-8bad-4c2d-aa72-36d8c138484e/
But as usual, you Google vb.Net and get answers in C#. I use C# to vb.net tool on the developerfusionwebsite to help me convert to vb.net but usually end up changing a fair amount.
Once you have a pointer this one is quite easy really.
In the dataGridView_CellPainting event add something like this
Private Sub InvoiceLinesDataGridView_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles InvoiceLinesDataGridView.CellPainting
If e.ColumnIndex = 3 AndAlso e.RowIndex >= 0 Then
e.Paint(e.CellBounds, DataGridViewPaintParts.All)
Dim bmpFind As Bitmap = My.Resources.binoc16_h1
Dim ico As Icon = Icon.FromHandle(bmpFind.GetHicon)
e.Graphics.DrawIcon(ico, e.CellBounds.Left + 3, e.CellBounds.Top + 3)
e.Handled = True
End If
End Sub
Just to explain this a little, I wanted to use a resource which is a bitmap so I am converting that to an icon also. This works really well for me and I get a proper button column with an image. The column index is a bit rough as that could change so I was looking to refer using the column name - shouldn't be too hard but you get the idea. SO much easier than the other options I have see around that get you making an extended custom column type.
This really should have just been part of the original control and I cannot fathom why MS crippled the grid so much. I have been trying to use third party controls like Telerik but the originals always seem to be more stable so am now seeing if I can stick with vanilla controls and adding my on extensions where required.
I created a method that can be called in the CellPainting datagridview event.
Public Shared Sub SetImageToDataGridViewButtonColumn_CallInCellPaintingEvent(ByRef img As Bitmap, e As System.Windows.Forms.DataGridViewCellPaintingEventArgs)
e.Paint(e.CellBounds, DataGridViewPaintParts.All & (DataGridViewPaintParts.ContentBackground) & (DataGridViewPaintParts.ContentForeground))
Dim destRect As Rectangle = New Rectangle(e.CellBounds.X + (e.CellBounds.Width - img.Width) / 2, e.CellBounds.Y + (e.CellBounds.Height - img.Height) / 2, img.Width, img.Height)
Dim srcRect As Rectangle = New Rectangle(0, 0, img.Width, img.Height)
e.Graphics.DrawImage(img, destRect, srcRect, GraphicsUnit.Pixel)
e.Handled = True
End Sub
In the CellPainting event, call this method passing the image you want on the button and e. Ensure you use some sort of condition to set on the column you need, this example the If specifies column 0. Also notice I have my image in My.Resources:
Private Sub dgv_CellPainting(sender As Object, e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles dgv.CellPainting
If (e.ColumnIndex = 0 And e.RowIndex >= 0) Then
SetImageToDataGridViewButtonColumn_CallInCellPaintingEvent(My.Resources.myImg, e)
End If
End Sub
Tips: I found 16x16 png were perfect for my use. You can resize using http://images.my-addr.com/resize_png_online_tool-free_png_resizer_for_web.php
You can try using a DataGridViewImageColumn add attach an event to the grid's CellContentClick event (in the event process only the events comming from the column/columns that is/are images)