Drawing bitmaps via BitmapBrush onto SlimDX Geometry (VB.NET ) - vb.net

I have a program where I am attempting to render an image in Direct2D onto a quadrilateral using SlimDX and VB.net.
The program gets an array of 4 points from a server, which are a quadrilateral, where the image should be rendered onto.
The points (For example) are:
points(0) = 20,10 <--Top left, where the geometry starts from
points(1) = 40,10 <-- Top right
points(2) = 40,40 <-- Bottom right
points(3) = 20,40 <-- Bottom left
...A BitmapBrush is constructed when loading and the Bitmap can be rendered fine, but when trying to render onto the quadrilateral, I only get (it seems...) some part the bottom right corner.
For reference: Here is the image I'm trying to draw:
http://i.imgur.com/Dt3iHQ3.png
And here is the code that I'm trying to use (for drawing the image).
R is the point list (see above) and RenderBrush is a BitmapBrush created from a 20x30 version of that image.
Private Sub DrawPoly(R() As PointF, ByRef RenderBrush As SlimDX.Direct2D.BitmapBrush)
'Create the geometry
Dim Path As PathGeometry
Path = New PathGeometry(factoryD2D)
Console.Clear()
'Get a handle to the Geometry
Dim Geometry = Path.Open()
'Set UP Geometry
Geometry.BeginFigure(R(0), FigureBegin.Filled)
Geometry.AddLines(R)
Geometry.EndFigure(FigureEnd.Closed)
Geometry.Close()
'Render
D2DRenderTarget.FillGeometry(Path, RenderBrush)
'and GC
Geometry.Dispose()
Path.Dispose()
End Sub
Thanks in advance for your help!

I figured it out. To get it to draw onto the geometry, you need to set up a transformation matrix like so:
Matrix3x2.Multiply(Matrix3x2.Translation(Point_To_Move_To), Matrix3x2.Rotation(Rotation, Point_To_Rotate_Around))

Related

Draw Image to Picture Box using AutoScroll but keep a Header Visible

I have a Picturebox which I draw a view to (Gantt View in this case) and it works OK - i.e., the view is drawn and the AutoScroll property allows the image in the PictureBox to be smoothly scrolled.
My problem is, the header of the image (e.g., the date headers in this case) scroll off the top of the display when I scroll down the image.
What I can't work out is how to fix a header to the top. I thought about simply drawing a header into another Picturebox, but then I am not sure how to sync the header with the left-right scrolling of the main PictureBox
Can someone suggest the best approach to handling this, or do I need to revert to doing a direct draw and handle the scrolling myself?
I am using VB with VS 2015.
Many thanks
Phil
Updated - I am now using an off-screen Bitmap, but can someone look at the code below and let me know if there is a faster/better way to do this? It all works, but still learning and so always looking to do things the best way
Public Sub MoveViewPoint(G As Graphics)
' G passed in from controls Paint
G.Clear(Color.WhiteSmoke)
' _Plan is off-screen bitmap of image
' _HeaderHeight is height of the Header area in _Plan
Dim Header_src_rect As New Rectangle(_HScroll.Value, 0, _Plan.Width, _HeaderHeight)
Dim Header_dst_rect As New Rectangle(0, 0, _Plan.Width, _HeaderHeight)
G.DrawImage(_Plan, Header_dst_rect, Header_src_rect, GraphicsUnit.Pixel)
Dim src_rect As New Rectangle(_HScroll.Value, _HeaderHeight + 1 + _VScroll.Value, _Plan.Width, _Plan.Height)
Dim dst_rect As New Rectangle(0, _HeaderHeight + 1, _Plan.Width, _Plan.Height)
G.DrawImage(_Plan, dst_rect, src_rect, GraphicsUnit.Pixel)
_HScroll.LargeChange = G.ClipBounds.Width * 0.9
_VScroll.LargeChange = G.ClipBounds.Height * 0.9
End Sub
I would do all your drawing to an off-screen bitmap using the GDI graphics system. You can draw your headers and the rest of the chart as 2 distinct stages in the same bitmap. You would have to handle the scrolling yourself by watching the MouseMove event and checking the buttons status.

Image array help in Silverlight

I'm Back! And having more Silverlight issues (yay!)
I am trying to create an image array in Silverlight but the images are not appearing on the page. Here is my code:
Public imgImages(50) As Image
Public Sub Create_Image_Array()
Dim I As Integer
For I = 0 To 50
imgImages(I) = New Image
imgImages(I).SetValue(Canvas.LeftProperty, System.Convert.ToDouble(0))
imgImages(I).SetValue(Canvas.TopProperty, System.Convert.ToDouble(0))
imgImages(I).Name = "imgImages" & I
imgImages(I).Width = System.Convert.ToDouble(18)
imgImages(I).Height = System.Convert.ToDouble(18)
imgImages(I).Source = New BitmapImage(New Uri("/Resources/yellow2.png", UriKind.Relative))
imgImages(I).Visibility = Windows.Visibility.Visible
AddHandler imgImages(I).MouseLeftButtonUp, AddressOf ImageClickEventProc
Next I
End Sub
Public Sub Draw_Images()
For I = 1 To secObject.intNumberOfImages
imgImages(I).SetValue(Canvas.LeftProperty, System.Convert.ToDouble(secObject.Images(I).intPosX))
imgImages(I).SetValue(Canvas.TopProperty, System.Convert.ToDouble(secObject.Images(I).intPosY))
imgImages(I).Visibility = Windows.Visibility.Visible
Next I
End Sub
The image array is created when the page is navigated to and then the page requests location information from a server and once it has that information it sets the X and Y coordinates of the images. All that part works fine - that was apparently the easy part - All the coordinate information is received and stored in secObject, the data is there. The URI for the resource of the image is there and it is valid, I tested it with another image control on the page.
The problem is that the little images are not displaying. I have tried numerous ways of getting them to display. I have found code on Google that does almost the exact same thing that I am trying to do and it is written in a similar way just for non-arrayed images.
I also tried another suggestion, to use TranslateTransform to set the positions of the images. This did nothing.
Dim tt As New TranslateTransform
tt.X = secObject.Images(I).intPosX
tt.Y = secObject.Images(I).intPosY
imgImages(I).RenderTransform = tt
I also removed the background image on the screen thinking that maybe the images were rendering below the background, and that is not the case.
Am I missing something? I admit to being a Silverlight n00b...
Thanks
-RW
OK I finally figured it out... I needed to create add the controls to the canvas:
LayoutRoot.Children.Add(imgImages(I))

VB.NET Winforms: Overlay two transparent images

I am attempting to overlay two transparent images within a winform, but it keeps rendering the form's background image behind the top transparent image, as opposed to the second image...
My basic set up is I have two panels and in each panel is a picturebox. Each image in the picture boxes have some transparent areas. I've set the BackColor of the panels to color.transparent.
When I make one panel overlay the other I'm seeing the form's backcolor come through as opposed to the underlaying image.
Am I missing a property that I can set?
You only need one picture box. The overlay can be done with graphics.
Imports System.Drawing
Dim OverlayImage As New Bitmap("Some Path", True)
Dim BackImage As New Bitmap("Some Path", True)
g As Graphics = Graphics.FromImage(BackImage)
g.DrawImage(OverlayImage, 0, 0)
pictureBox1.Image = BackImage
If you want to have the timer move the overlayed image, then first, make a variable Dim posX As Integer = 0
then use g.DrawImage(OverlayImage, posX, 0) Now when your timer ticks, increment posX by 10
Here's a complete function to overlay two images (adapted from Blue0500's answer):
''' <summary> Return a new image with one superimposed over the other. </summary>
Function OverlayImgs(ByVal BackgroundImg As System.Drawing.Bitmap, ByVal OverlayImg As System.Drawing.Bitmap, Position As System.Drawing.Point) As System.Drawing.Bitmap
Dim g = System.Drawing.Graphics.FromImage(BackgroundImg)
g.DrawImage(OverlayImg, Position)
Return BackgroundImg
End Function
Usage:
lblTest.Image = OverlayImgs(Img1, Img2, New Point(16, 16))
You don't need a PictureBox for this unless you are using it for the canvas. You can draw all images to a Rectangle structure and move them around. Personally I would create a class object that has a Rectangle, Image and other properties and hold them in a collection. Then you simply draw the class objects by there properties including location. If there images contain transparencies they will overlay for you. This also gives you a method to check for collisions via the Rectangle.IntersectsWith function.

Windows 8 App - Programmatically Added Path Disappears

Any help with this would be much appreciated.
I am trying to build an app in Windows 8 using xaml and vb.
To test the process of adding a path dynamically to the UI I have created a class that draws a circle using a path (code below). The code fires when a button is tapped/clicked.
The circle then appears briefly near the centre of the screen but then disappears.
If I then count the children on the grid, the circle is counted. Its just not visible.
I'd like to understand what is happening and stop the circle from disappearing.
Dim path As New Windows.UI.Xaml.Shapes.Path
Dim rectG As New EllipseGeometry
rectG.Center = New Point(500, 500)
rectG.RadiusX = 100
rectG.RadiusY = 100
path.Data = rectG
path.Stroke = New SolidColorBrush(Windows.UI.Colors.LightGreen)
path.StrokeThickness = 1
path.Fill = New SolidColorBrush(Windows.UI.Colors.LightGreen)
path.Name = "TestName"
_TargetGrid.Children.Add(path)
Finally figured it out. I needed to set the column and row span property.
On the test I did it using the code although in a proper app it would probably make sense to use some kind of predetermined styling.
However, here is the code I added:
path.SetValue(Grid.ColumnSpanProperty, 5)
path.SetValue(Grid.RowSpanProperty, 5)

How to Draw above a picture in VB.NET

I am building a 2D game where the user is a circle(:P) and the enemies are rectangles coming at him. However, my problem is that when I placed a very nice picture of space I found on the internet, the screen draws whatever it has to underneath this image. Everything works,I can still see my lives going down when something collides into me - except the fact it is all covered up by this picture.
In a nutshell, my question is: How Do I Draw everything ON Top of this - (I tried using the 'Send To Back' Command)
EDIT: The form draws everything through a timer, and the user controls his character through keys. This probably won't help - but if it does it's here.
Sorry folks didn't think you'd need the code. Here it is:
In the mybase.load procedure:
PicBackGround.Dock = DockStyle.Fill
PicBackGround is the picture box with the image.
In the paint procedure:
e.Graphics.Clear(Color.Black)
e.Graphics.FillEllipse(Brushes.Orange, Player)
'Projectiles
Dim i As Integer = 0
Do
If Current_Projectile(i).IsEmpty = False Then e.Graphics.FillRectangle(Brushes.Red, Current_Projectile(i))
i += 1
Loop Until i = UBound(Current_Projectile)
'Objects
i = 0
Do
If Objects(i).IsEmpty = False Then e.Graphics.FillRectangle(Brushes.Blue, Objects(i))
i += 1
Loop Until i = UBound(Objects)
Okay: Player is a rectangle declared right at the top, Dim Player As New Rectangle(0, 0, 50, 50);
There is then the array Objects, which stores all the data about the enemies coming at the player, Current_Projectiles is simply an array to store data about rectangles(bullets) that the player fires.
Anything else you want to know just let me know.
Yes, a control overlaps anything you draw on the form. A simple solution is to use the form's BackgroundImage property instead. Or draw the image yourself.