vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
Go Back  Xtreme Visual Basic Talk > > > vb.net how to create a region or path from a bitmap or image


Reply
 
Thread Tools Display Modes
  #1  
Old 10-22-2006, 09:42 PM
Gib Gib is offline
Newcomer
 
Join Date: Oct 2006
Posts: 8
Default vb.net how to create a region or path from a bitmap or image


Hello Gurus, 1st time posting here.

I came up with an algorithm for my tactical space combat game that fits a picture box to its non-transparent pixels (creates a region from the gif the picturebox contains) and it works great, but its slow since it iterates through all the pixels in the picbox and forms unions of regions to yield the final region. The code can be found here:

http://vb-helper.com/howto_net_shape_pic.html

My starship combat game needs to be able to handle mouse clicks on the ships to set them as the active ship or to target an enemy ship in a particular fire arc(fore, aft, port, starboard). This is why I went with a picture box since its easy to code with as it has almost all the properties and methods and events I need for a non-flashy board game on the pc.

I was wondering if there was a way to get the outline of a gif image(bitmap object or image object) in vb.net and use that as a series of points to construct a polygon and then in turn use the polygon to contruct a path and then finally a region from that path. I have spent alot of hours Googleing to no avail. There must be some way of tracing an outline of an image to yield the points and then do the rest. Anybody have code for this or have a link or ideas on how? The drawing classes and gdi are powerful but so far I've played around with different types and methods on the classes and have come up short.

Then I can create the region for the ships gifs and use mouse clicks to test region.isvisible to return what ship was clicked on and it will be faster I assume. Otherwise I need to make 6 copies of my images region - 1 per 60 degree rotation since im using a hex map. I suppose I could do this during the loading screen and keep them in memory to use them when a ship is rotated and then the rotation would be instant(comparatively)

Sorry for the long winded post. Any help would be appreciated. Let me know if you need anything clarified.

Thanks!

Dave Giblin
"Gib"
Reply With Quote
  #2  
Old 10-23-2006, 12:15 AM
Gib Gib is offline
Newcomer
 
Join Date: Oct 2006
Posts: 8
Default

You can tell I am tired because my code I have IS the solution. I've been chasing this thing all day lol.

All I need to do is to copy my function for generating a region and create a new function and modify it.

IE: Perform a bitmap scan of the gif by using the getpixel function of GDI as I am doing it but go to the next line of pixels down once the color of the pixel read is different from the transparent color and add that point(as a new point(x,y) to an array of points. This will find the left side of the bitmap outline. Once at the bottom of the picture then start reading bottom up right to left to find the right side of the bitmap outline. Then I have an array of points that make up a system.drawing.drawing.graphicspath. Then I just make a region from that path and viola, old fashioned bitblt with a mask (sort of). Since I can then use isvisible to hit test for mouse clicks in a region, I have my objective of being able to mouse click on a picture!

Also check out
http://www.codeproject.com/cs/miscct...rary_shape.asp

This guy did the same thing and after comming across it tonight I had to hit my forhead(doh!) with my palm as I realized that's what my code was doing, I was just getting too many pixels and thus the process took much longer.

I'll code it in the morning and post back here in case anybody else ever needs it.

Gib
Reply With Quote
  #3  
Old 10-23-2006, 02:17 PM
Gib Gib is offline
Newcomer
 
Join Date: Oct 2006
Posts: 8
Default



Well I didn't think about something until now, the technique of "scanning" a bitmap for its pixels that are on the outside edge around it to yield a region that is an outline of a bitmap will not work so I might as well use my original and go with my alternative idea.

While doing it I realized you would have to scan the 4 faces of the "box" that hold the image in the bitmap. In doing do, I realized that complex shapes could not be done.

The ONLY way is to iterate through every pixel in a bitmap to find the region that's just the actual image. This is becasue, and unless someone can show otherwise, the gdi drawing classes dont have a way to create a region nor a path or polygon trace of the outline of a bitmap.

If anyone has any ideas please let me know!


Gib
Reply With Quote
  #4  
Old 10-24-2006, 02:38 AM
Cags's Avatar
Cagsvb.net how to create a region or path from a bitmap or image Cags is offline
Contributor

* Expert *
 
Join Date: Jul 2003
Location: Leicestershire, England
Posts: 710
Default

Is this the kind of thing your after?
__________________
I don't suffer from insanity, I enjoy every minute of it.
http://www.tib-studios.co.uk
Reply With Quote
  #5  
Old 10-24-2006, 10:53 PM
Gib Gib is offline
Newcomer
 
Join Date: Oct 2006
Posts: 8
Default

Quote:
Originally Posted by Cags
Is this the kind of thing your after?
That's what im doing right now yes, and it works. The problem is, it's using getpixel on every pixel in the picturebox and its slow. Then I rotate my picture using my rotate sub I then call my GetRegion which gets a new region for the rotated image and sets the picture box region. This works fine but has a noticeable lag in rotating.

What I was trying to do now was pre define 6 roation regions and the rotated bitmap image and store them. That way the the loading is on the front end when the game loads for each differnt ship image. My problem now is that when I do the first rotation and set my ship's image property to the stored rotated image and also set the ships region property to the stored region for that rotation it doesnt seem to fully set the region of my pictureox - the previous region is mixed into the new region of sorts.

Here's the core subs/functions - let me know if you need more to figure out

The code is messy right now because I was just trying various things out, hope you can understand the rest. If you want I could post some more but this is the core stuff - i left out the classes and structures and whatnot
Code:
[COLOR=Blue]Private Function GetRegion(ByVal bm As Bitmap, ByVal bg_color As Color) As Region[/COLOR] Dim new_region As New Region new_region.MakeEmpty() Dim rect As New Rectangle Dim in_image As Boolean = False Dim X As Integer For Y As Integer = 0 To bm.Height - 1 X = 0 Do While (X < bm.Width) If Not in_image Then If Not bm.GetPixel(X, Y).Equals(bg_color) Then in_image = True rect.X = X rect.Y = Y rect.Height = 1 End If ElseIf bm.GetPixel(X, Y).Equals(bg_color) Then in_image = False rect.Width = (X - rect.X) new_region.Union(rect) End If X = (X + 1) Loop ' Add the final piece if necessary. If in_image Then in_image = False rect.Width = (bm.Width - rect.X) new_region.Union(rect) End If Next Y Return new_region End Function [COLOR=Blue]Public Function RotateShip(ByVal Angle As Integer, ByVal m_SourceBm As Bitmap) 'ByVal Index As Integer,[/COLOR] Try 'Dim MyImage As String = Application.StartupPath & "\Ships\" & Ship(Index).Name & ".gif" 'Dim m_SourceBm As New Bitmap(Application.StartupPath & "\Ships\" & Ship(Index).Name & ".gif") Dim m_SourceWid As Integer = m_SourceBm.Width Dim m_SourceHgt As Integer = m_SourceBm.Height Dim m_SourceCx As Single = m_SourceWid / 2 Dim m_SourceCy As Single = m_SourceHgt / 2 Dim m_SourceCorners As PointF() Dim m_DestWid As Integer Dim m_DestHgt As Integer Dim m_DestCx As Single Dim m_DestCy As Single Dim m_DestBm As Bitmap Dim m_DestBackColor As Color m_SourceCorners = New PointF() _ {New PointF(0, 0), _ New PointF(m_SourceWid, 0), _ New PointF(0, m_SourceHgt), _ New PointF(m_SourceWid, m_SourceHgt)} m_DestWid = m_SourceBm.Width m_DestHgt = m_SourceBm.Height m_DestCx = m_DestWid / 2 m_DestCy = m_DestHgt / 2 m_DestBm = New Bitmap(m_DestWid, m_DestHgt) ' Translate the corners to center the bounding box at the origin. Dim i As Long For i = 0 To 3 m_SourceCorners(i).X -= m_SourceCx m_SourceCorners(i).Y -= m_SourceCy Next i 'Save picDest's background color. m_DestBackColor = Color.Transparent 'pbShip.BackColor Dim theta As Single = Angle * PI / 180 'Make a local copy of the image's corners. Dim corners() As PointF = m_SourceCorners 'Drop the last corner lest we confuse DrawImage which expects an array of three corners. ReDim Preserve corners(2) 'Rotate. Dim sin_theta As Single = Math.Sin(theta) Dim cos_theta As Single = Math.Cos(theta) Dim X As Single Dim Y As Single For i = 0 To 2 X = corners(i).X Y = corners(i).Y corners(i).X = X * cos_theta + Y * sin_theta corners(i).Y = -X * sin_theta + Y * cos_theta Next i 'Translate to center the results in the destination image. For i = 0 To 2 corners(i).X += m_DestCx corners(i).Y += m_DestCy Next i 'Create an output Bitmap and Graphics object. Dim gr_out As Graphics = Graphics.FromImage(m_DestBm) 'Draw the result onto the output Bitmap. gr_out.Clear(m_DestBackColor) gr_out.DrawImage(m_SourceBm, corners) 'Display the result. ' pbShip.Image = m_DestBm Return m_DestBm Catch ex As Exception Return m_SourceBm End Try End Function [COLOR=Blue]Private Sub frmStarshipCombat_KeyPress _ (ByVal sender As Object, _ ByVal e As System.Windows.Forms.KeyPressEventArgs) _ Handles Me.KeyPress [/COLOR] Try pbShip.Visible = False pbShip.BringToFront() If Game.Phase = "Movement" Then Select Case Game.Ship Case 0, 1, 2 If Game.Player = 1 Then If Ship(Game.Ship).MoveLeft > 0 Then Select Case UCase(e.KeyChar) Case "W" 'Move the ship forward 1 hex in the direction it's facing Select Case Ship(Game.Ship).Facing Case 1 pbShip.Top -= HexYIncr Case 2 pbShip.Top -= (0.5 * HexYIncr) pbShip.Left += HexXIncr Case 3 pbShip.Top += (0.5 * HexYIncr) pbShip.Left += HexXIncr Case 4 pbShip.Top += HexYIncr Case 5 pbShip.Top += (0.5 * HexYIncr) pbShip.Left -= HexXIncr Case 6 pbShip.Top -= (0.5 * HexYIncr) pbShip.Left -= HexXIncr End Select Case "A" 'Rotate the ship 60 degrees counter-clockwise Ship(Game.Ship).Facing -= 1 If Ship(Game.Ship).Facing < 0 Then Ship(Game.Ship).Facing = 5 End If pbShip.Image = Ship(Game.Ship).Image(Ship(Game.Ship).Facing) pbShip.Region = Ship(Game.Ship).Region(Ship(Game.Ship).Facing) 'RotateShip((Ship(Game.Ship).Facing - 1) * -60, Game.Ship) 'Dim ShipImage As New Bitmap(pbShip.Image) 'pbShip.Region = BitmapToRegion(ShipImage, ShipImage.GetPixel(0, 0)) Case "D" 'Rotate the ship 60 degrees clockwise Ship(Game.Ship).Facing += 1 If Ship(Game.Ship).Facing > 5 Then Ship(Game.Ship).Facing = 0 End If pbShip.Image = Ship(Game.Ship).Image(Ship(Game.Ship).Facing) pbShip.Region = Ship(Game.Ship).Region(Ship(Game.Ship).Facing) 'RotateShip((Ship(Game.Ship).Facing - 1) * -60, Game.Ship) 'Dim ShipImage As New Bitmap(pbShip.Image) 'pbShip.Region = BitmapToRegion(ShipImage, ShipImage.GetPixel(0, 0)) End Select pbShip.Invalidate() End If End If Case Else If Game.Player = 1 Then End If End Select End If pbShip.Visible = True Catch ex As Exception MsgBox(ex.Message & vbCrLf & vbCrLf & "frmStarshipCombat.KeyPress" & vbCrLf & Ship(Game.Ship).Facing) End Try End Sub

Last edited by DougT; 10-24-2006 at 11:21 PM. Reason: Put in vb tags
Reply With Quote
  #6  
Old 10-24-2006, 10:55 PM
Gib Gib is offline
Newcomer
 
Join Date: Oct 2006
Posts: 8
Default

Code:
Public Sub GetRotatedImageAndRegion(ByVal bitmap As Bitmap) 'test code for now, need to put in a 0-5 loop to clean up Try 'Facing 0 Dim image0 As New Bitmap("E:\StarshipCombat\StarshipCombat\bin\Debug\Ships\Klingon D7.gif") image0 = bitmap pb0.BackColor = Color.Transparent pb0.SizeMode = PictureBoxSizeMode.AutoSize pb0.Top = 100 pb0.Left = 100 pb0.Visible = True pb0.Image = image0 'picHexGrid.Controls.Add(pb0) pb0.Region = BitmapToRegion(image0, image0.GetPixel(0, 0)) pb0.Image = RotateShip(0, image0) Ship(Game.Ship).Image(0) = pb0.Image Dim ShipImage0 As New Bitmap(pb0.Image) pb0.Region = BitmapToRegion(ShipImage0, ShipImage0.GetPixel(0, 0)) Ship(Game.Ship).Region(0) = pb0.Region 'Facing 1 Dim image1 As New Bitmap("E:\StarshipCombat\StarshipCombat\bin\Debug\Ships\Klingon D7.gif") image1 = bitmap pb1.BackColor = Color.Transparent pb1.SizeMode = PictureBoxSizeMode.AutoSize pb1.Top = 100 pb1.Left = 200 pb1.Visible = True pb1.Image = image1 'picHexGrid.Controls.Add(pb1) pb1.Region = BitmapToRegion(image1, image1.GetPixel(0, 0)) pb1.Image = RotateShip(-120, image1) Ship(Game.Ship).Image(1) = pb1.Image Dim ShipImage1 As New Bitmap(pb1.Image) pb1.Region = BitmapToRegion(ShipImage1, ShipImage1.GetPixel(0, 0)) Ship(Game.Ship).Region(1) = pb1.Region 'Facing 2 Dim image2 As New Bitmap("E:\StarshipCombat\StarshipCombat\bin\Debug\Ships\Klingon D7.gif") image2 = bitmap pb2.BackColor = Color.Transparent pb2.SizeMode = PictureBoxSizeMode.AutoSize pb2.Top = 100 pb2.Left = 200 pb2.Visible = True pb2.Image = image2 'picHexGrid.Controls.Add(pb2) pb2.Region = BitmapToRegion(image2, image2.GetPixel(0, 0)) pb2.Image = RotateShip(-120, image2) Ship(Game.Ship).Image(2) = pb2.Image Dim ShipImage2 As New Bitmap(pb2.Image) pb2.Region = BitmapToRegion(ShipImage2, ShipImage2.GetPixel(0, 0)) Ship(Game.Ship).Region(2) = pb2.Region 'Facing 3 Dim image3 As New Bitmap("E:\StarshipCombat\StarshipCombat\bin\Debug\Ships\Klingon D7.gif") image3 = bitmap pb3.BackColor = Color.Transparent pb3.SizeMode = PictureBoxSizeMode.AutoSize pb3.Top = 100 pb3.Left = 200 pb3.Visible = True pb3.Image = image3 'picHexGrid.Controls.Add(pb3) pb3.Region = BitmapToRegion(image3, image3.GetPixel(0, 0)) pb3.Image = RotateShip(-120, image3) Ship(Game.Ship).Image(3) = pb3.Image Dim ShipImage3 As New Bitmap(pb3.Image) pb3.Region = BitmapToRegion(ShipImage3, ShipImage3.GetPixel(0, 0)) Ship(Game.Ship).Region(3) = pb3.Region 'Facing 4 Dim image4 As New Bitmap("E:\StarshipCombat\StarshipCombat\bin\Debug\Ships\Klingon D7.gif") image4 = bitmap pb4.BackColor = Color.Transparent pb4.SizeMode = PictureBoxSizeMode.AutoSize pb4.Top = 100 pb4.Left = 200 pb4.Visible = True pb4.Image = image4 'picHexGrid.Controls.Add(pb4) pb4.Region = BitmapToRegion(image4, image4.GetPixel(0, 0)) pb4.Image = RotateShip(-120, image4) Ship(Game.Ship).Image(4) = pb4.Image Dim ShipImage4 As New Bitmap(pb4.Image) pb4.Region = BitmapToRegion(ShipImage4, ShipImage4.GetPixel(0, 0)) Ship(Game.Ship).Region(4) = pb4.Region 'Facing 5 Dim image5 As New Bitmap("E:\StarshipCombat\StarshipCombat\bin\Debug\Ships\Klingon D7.gif") image5 = bitmap pb5.BackColor = Color.Transparent pb5.SizeMode = PictureBoxSizeMode.AutoSize pb5.Top = 100 pb5.Left = 200 pb5.Visible = True pb5.Image = image5 'picHexGrid.Controls.Add(pb5) pb5.Region = BitmapToRegion(image5, image5.GetPixel(0, 0)) pb5.Image = RotateShip(-120, image5) Ship(Game.Ship).Image(5) = pb5.Image Dim ShipImage5 As New Bitmap(pb5.Image) pb5.Region = BitmapToRegion(ShipImage5, ShipImage5.GetPixel(0, 0)) Ship(Game.Ship).Region(5) = pb5.Region 'Dim image(5) As Bitmap 'Dim i As Integer 'For i = 0 To 5 ' Dim pb As New PictureBox ' Dim newimage As Bitmap = bitmap '("E:\StarshipCombat\StarshipCombat\bin\Debug\Ships\Klingon D7.gif") ' pb.BackColor = Color.Transparent ' pb.SizeMode = PictureBoxSizeMode.AutoSize ' pb.Top = 100 ' pb.Left = 100 ' pb.Visible = True ' pb.Image = newimage ' picHexGrid.Controls.Add(pb) ' pb.Region = BitmapToRegion(newimage, newimage.GetPixel(0, 0)) ' pb.Image = RotateShip((i * -60), newimage) ' Dim ShipImage As New Bitmap(pb.Image) ' pb.Region = BitmapToRegion(ShipImage, ShipImage.GetPixel(0, 0)) ' Ship(Game.Ship).Region(i) = pb.Region ' pb.Dispose() 'Next 'image(i) = RotateShip(-60, newimage) 'Ship(Game.Ship).Image(i) = image(i) 'Dim pbship As New PictureBox 'Ship(Game.Ship).Region(i) = pbship.Region 'Ship(Game.Ship).Region(i) = BitmapToRegion(image(i), image(i).GetPixel(0, 0)) Catch ex As Exception MsgBox(ex.Message & vbCrLf & vbCrLf & "GetRotatedImageAndRegion") End Try End Sub

Last edited by webbone; 10-24-2006 at 11:14 PM.
Reply With Quote
  #7  
Old 10-24-2006, 11:06 PM
Gib Gib is offline
Newcomer
 
Join Date: Oct 2006
Posts: 8
Default

You're probably wondering why all this code to make a picturebox fit to its non-transparent pixels and be able to rotate images.

I could do all this with gdi drawing classes and just draw the transparent gif rotated on the game screen. BUT, and this is a huge BUTow do I, in GDI, tell if that bitmap has been clicked or moused over by the user? I would still have to create a region in order to detect region.isvisible(e.x, e.y) correct?

That's why I had to go with a picture box since It supports the needed mouse click detection - so the controls are intuitive. IE, click a ship to select it, click anywhere else on the hex grid(picturebox) to deselect or while selected, click on your target(and fire arcs get drawn and you select weapons in the fire arc to fire on the enemy vessel).

If there's no way to detect what gif was clicked on then I have to come up with something very ugly to enagle selecting ships/targets. There has to be a way...anyone know??

Thanks in advance,
Gib
Reply With Quote
  #8  
Old 10-29-2006, 03:34 PM
Gib Gib is offline
Newcomer
 
Join Date: Oct 2006
Posts: 8
Default

I finally got this son of a beep to work. Found out you have to PictureBox.Region.Dispose() before setting the region. Oh, you CAN set the region without doing this and will work fine but since my game rotates ships to hexside facings, Im holding 6 variables for each different ship gif in memory. In my test code I was getting it almost to work but when I set the region from 1 to 2 to 3... to 5 it worked but when I set it from 5 to 0 then I got a strange parmamter is not valid error. I stated screwing around with other methods contained in the region class and found dispose(). Now everything is well in the universe

If anybody is making games and wants to know all about rotating a image in a picture box and how to make that picturebox TRUELY transparent(by setting its' region to its' non-transparent pixels) let me know!

I cant believe MS left out direct bitmap access to convert bitmaps to paths and then regions in GDI+ and also true transparent picboxes!!!

Gib
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
 
vb.net how to create a region or path from a bitmap or image
vb.net how to create a region or path from a bitmap or image
 
-->