Function returning image
Function returning image
Function returning image
Function returning image
Function returning image
Function returning image Function returning image Function returning image Function returning image Function returning image Function returning image Function returning image Function returning image
Function returning image Function returning image
Function returning image
Go Back  Xtreme Visual Basic Talk > > > Function returning image


Reply
 
Thread Tools Display Modes
  #1  
Old 07-13-2014, 06:36 PM
Rodrigo Mota Rodrigo Mota is offline
Regular
 
Join Date: Apr 2005
Location: Portugal
Posts: 53
Default Function returning image


Hi guys, I'm stuck in this for quite sometime and I don't even know if what I want is possible.
Sorry about the title it doesn't describe exactly what I pretend but I didn't know how to put it.
So here it goes, I've drawn a shape with GDI and I want to be able to put it in a function in order to get it whenever I want and pass the parameters.

Here's the code:

Code:
Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)

        'VÁLVULA 40 X 40
        Dim t1 As New Point(0, 10)
        Dim t2 As New Point(0, 30)
        Dim t3 As New Point(20, 20)
        Dim t4 As New Point(40, 10)
        Dim t5 As New Point(40, 30)
        Dim t6 As New Point(20, 10)
        Dim r2 As Rectangle = New Rectangle(10, 0, 20, 20)

        Dim aIni As Single = 0
        Dim aAmp As Single = -180
        Dim l As Pen = New Pen(Brushes.Black, 2)

        Dim vT1 As Point() = {t1, t2, t3}
        Dim vT2 As Point() = {t3, t4, t5}

        Dim vP As Bitmap = New Bitmap(40, 40)
        Dim vPeq As Graphics = Me.CreateGraphics
        vPeq = Graphics.FromImage(vP)
        With vPeq
            .FillPolygon(Brushes.Yellow, vT1)
            .DrawPolygon(l, vT1)
            .FillPolygon(Brushes.Yellow, vT2)
            .DrawPolygon(l, vT2)
            .FillPie(Brushes.Yellow, r2, aIni, aAmp)
            .DrawPie(l, r2, aIni, aAmp)
            .DrawLine(l, t3, t6)
        End With

        e.Graphics.DrawImage(vP, 50, 100)
    End Sub

End Class
This part works fine, what I want to do is having a function with the drawing part and be able to call from the sub.
I'll post what I tried to do with no success:

Code:
  Function valve(vt1() As Point, vt2() As Point, aIni As Single, anAmp As Single, l1 As Point, l2 As Point, r As Rectangle) As Graphics
        Dim l As Pen = New Pen(Brushes.Black, 2)
        With valve
            .FillPolygon(Brushes.Yellow, vt1)
            .DrawPolygon(l, vt1)
            .FillPolygon(Brushes.Yellow, vt2)
            .DrawPolygon(l, vt2)
            .FillPie(Brushes.Yellow, r, aIni, aAmp)
            .DrawPie(l, r, aIni, aAmp)
            .DrawLine(l, l1, l2)
        End With
        Return valve
    End Function
Is there a way of doing a function like this so that when I draw the image, I don't have to write the code every time.
I'm still taking my 1st steps in .net so I'm struggling a bit with all the concepts around it.

I hope I explained myself clearly and looking forward for some help.
Thank you very much for your time and patience.
Reply With Quote
  #2  
Old 07-14-2014, 06:17 AM
Rodrigo Mota Rodrigo Mota is offline
Regular
 
Join Date: Apr 2005
Location: Portugal
Posts: 53
Default

Think I found a solution, I'm posting it as it might help someone with a similar problem.
Going to start playing with the parameters of the function now
Cheers.

Code:
Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        e.Graphics.DrawImage(drawValve(), 50, 100)
    End Sub

    Function drawValve() As Bitmap
        'VÁLVULA 40 X 40
        Dim t1 As New Point(0, 10)
        Dim t2 As New Point(0, 30)
        Dim t3 As New Point(20, 20)
        Dim t4 As New Point(40, 10)
        Dim t5 As New Point(40, 30)
        Dim t6 As New Point(20, 10)
        Dim r2 As Rectangle = New Rectangle(10, 0, 20, 20)

        Dim aIni As Single = 0
        Dim aAmp As Single = -180
        Dim l As Pen = New Pen(Brushes.Black, 2)

        Dim vT1 As Point() = {t1, t2, t3}
        Dim vT2 As Point() = {t3, t4, t5}

        Dim vP As Bitmap = New Bitmap(40, 40)
        Dim vPeq As Graphics = Me.CreateGraphics
        vPeq = Graphics.FromImage(vP)

        With vPeq
            .FillPolygon(Brushes.Yellow, vT1)
            .DrawPolygon(l, vT1)
            .FillPolygon(Brushes.Yellow, vT2)
            .DrawPolygon(l, vT2)
            .FillPie(Brushes.Yellow, r2, aIni, aAmp)
            .DrawPie(l, r2, aIni, aAmp)
            .DrawLine(l, t3, t6)
        End With
        Return vP
    End Function
Reply With Quote
  #3  
Old 07-15-2014, 09:13 AM
Gruff's Avatar
GruffFunction returning image Gruff is offline
Bald Mountain Survivor

Retired Moderator
* Expert *
 
Join Date: Aug 2003
Location: Oregon, USA - deceased
Posts: 6,440
Default

I believe you are going about it backwards.

You should be passing the e.Graphics object to a sub routine.

Draw on the graphics object in your sub routine.
Code:
Imports System.Drawing

Public Class Form1
  Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    DrawValve(e.Graphics, 40, 50)
  End Sub

  Private Sub DrawValve(g As Graphics, x As Integer, y As Integer)
    Dim t1 As New Point(0, 10)
    Dim t2 As New Point(0, 30)
    Dim t3 As New Point(20, 20)
    Dim t4 As New Point(40, 10)
    Dim t5 As New Point(40, 30)
    Dim t6 As New Point(20, 10)
    Dim r2 As Rectangle = New Rectangle(10, 0, 20, 20)

    Dim aIni As Single = 0
    Dim aAmp As Single = -180
    Dim l As Pen = New Pen(Brushes.Black, 2)

    Dim vT1 As Point() = {t1, t2, t3}
    Dim vT2 As Point() = {t3, t4, t5}

    With g
      .TranslateTransform(x, y)

      .FillPolygon(Brushes.Yellow, vT1)
      .DrawPolygon(l, vT1)
      .FillPolygon(Brushes.Yellow, vT2)
      .DrawPolygon(l, vT2)
      .FillPie(Brushes.Yellow, r2, aIni, aAmp)
      .DrawPie(l, r2, aIni, aAmp)
      .DrawLine(l, t3, t6)
    End With

  End Sub
End Class
__________________
Burn the land and boil the sea
You can't take the sky from me


~T
Reply With Quote
  #4  
Old 07-19-2014, 06:32 PM
Rodrigo Mota Rodrigo Mota is offline
Regular
 
Join Date: Apr 2005
Location: Portugal
Posts: 53
Default

Thanks for your reply.
Could you explain more thoroughly, I don't understand very well what you mean.
Sorry, it's just I'm still learning .net and it's all a bit confusing.
Anyway the function seems to work fine could you explain what is happening with it.
Thank you for your help.
Reply With Quote
  #5  
Old 07-19-2014, 06:54 PM
Gruff's Avatar
GruffFunction returning image Gruff is offline
Bald Mountain Survivor

Retired Moderator
* Expert *
 
Join Date: Aug 2003
Location: Oregon, USA - deceased
Posts: 6,440
Default

If you mean explain my code then sure.

Painting takes place with the graphics object in VB.NET winforms.
The best way to get the graphics object is inside the Paint event.

The 'e' parameter in the paint event contains the graphics object that will be used for the surface of the form.
You can paint directly with this object or pass it to one or more sub routines and paint there.

The paint event is fired whenever windows determines it needs to be redrawn such as when another window passes across your form.

You can also force the paint event to fire by using the Invalidate command.
Basically this tells windows that the control or form you are painting on is dirty and needs to be refreshed.

Yes you can also use a control's paint event to paint on a control.

If you look at my subroutine the first parameter defined is of type Graphics.
If you do not understand what parameters are or how to create your own sub routines with parameters then you need to back up and get some more experience with simpler programs.

If you note I pass an X,Y coordinate to the sub routine. This allows you to place the valve anywhere on your form without having to hard code each of the valve drawing nodes.

Do you understand the use of the "With .. End With" structure?
__________________
Burn the land and boil the sea
You can't take the sky from me


~T
Reply With Quote
  #6  
Old 07-20-2014, 05:23 AM
Rodrigo Mota Rodrigo Mota is offline
Regular
 
Join Date: Apr 2005
Location: Portugal
Posts: 53
Default

First of all thank you for your time.
Yes I do understand parameters and passing them to subroutines and I think I understand the with ... end with structure, at least under a vb6 point of view.
My level of knowledge isn't very high (I'm just an amateur programmer) but I think I manage the basics.
I understand your code, what I didn't understand is what you meant by going backwards in my approach with the function.
I built a function so that I can access that object and change some of it's properties (like color, position), I reckon I can do that directly from the paint event passing the appropriate parameters, but how to do it run time?
My thought is that with the function, I just needed to call it and do the changes I wanted.
I'm sorry if I didn't explain myself clearly, but English isn't my native language and sometimes things aren't expressed as I intended.
Here is another piece of code to access and use the object.
This is only testing because I intend to have a whole bunch of valves scattered around the form and be able to access and change them individually.

Code:
 Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick

        Dim man As New SolidBrush(Color.Yellow)
        If e.X > 50 And e.X < 90 And e.Y > 100 And e.Y < 140 Then
            Dim g As Graphics
            g = Me.CreateGraphics
            g.DrawImage(drawValve(man), 50, 100)
        End If
    End Sub
Reply With Quote
  #7  
Old 07-20-2014, 02:49 PM
passel's Avatar
passelFunction returning image passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,015
Default

The "backwards" part is probably the inefficiency of your approach.
Your function has to create a bitmap, then draw on the bitmap, then return the bitmap and then the form has to draw the bitmap on the form.
So, there is time and resources spent creating the bitmap, drawing on the bitmap, only to have to draw the bitmap on the form.

With Gruff's approach, you just draw on the Form directly, saving a lot of time and resources.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #8  
Old 07-21-2014, 04:15 PM
Gruff's Avatar
GruffFunction returning image Gruff is offline
Bald Mountain Survivor

Retired Moderator
* Expert *
 
Join Date: Aug 2003
Location: Oregon, USA - deceased
Posts: 6,440
Default

Here is a rough sample that draws one of your valves in a selectable color at a selectable angle wherever the mouse clicks. See the attached Pic below.

Note we are using a list(of type) to store the items we want to draw
inside the paint event. We do this because the entire list needs to be redrawn every time the picturebox repaints.

The Item to be drawn is given a number (by you.)
The drawing sub routines draw the shape that matches the number.

Map is a picturebox control we draw on
lstColors is a listbox control
lstItemTypes is a listbox control

Notice the map.invalidate statement that causes a redraw.

Code:
Imports System.Drawing Public Class Form1 Public ItemList As New List(Of clsItem) Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load lstItemTypes.SelectedIndex = 0 lstColors.SelectedIndex = 0 lstAngle.SelectedIndex = 0 End Sub Private Sub Map_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Map.MouseClick ' Create Items at location selected Dim sType As String = lstItemTypes.SelectedItem.ToString Dim oColor As Color = Color.FromName(lstColors.SelectedItem.ToString) Dim nAngle As Integer = CInt(lstAngle.SelectedItem.ToString) Select Case sType Case "Valve" ItemList.Add(New clsItem(1, oColor, e.Location, nAngle)) Map.Invalidate() Case "BallValve" '... End Select End Sub Private Sub Map_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Map.Paint If ItemList.Count > 0 Then For Each Item As clsItem In ItemList Select Case Item.ItemType Case 1 DrawValve(e.Graphics, Item.Color, Item.Pt, Item.Angle) Case 2 '... End Select Next End If End Sub Private Sub DrawValve(g As Graphics, ItemColor As Color, ItemPt As Point, ItemAngle As Integer) 'Coordinates 0,0 are will be where the mouse cursor is located. 'If you want the valve to be located from the center of the valve 'You need to change the coordinate points below to reflect that condition. Dim t1 As New Point(0, 10) Dim t2 As New Point(0, 30) Dim t3 As New Point(20, 20) Dim t4 As New Point(40, 10) Dim t5 As New Point(40, 30) Dim t6 As New Point(20, 10) Dim r2 As Rectangle = New Rectangle(10, 0, 20, 20) Dim aIni As Single = 0 Dim aAmp As Single = -180 Dim l As Pen = New Pen(Brushes.Black, 2) Dim vT1 As Point() = {t1, t2, t3} Dim vT2 As Point() = {t3, t4, t5} With g Dim B1 As Brush = New SolidBrush(ItemColor) .TranslateTransform(ItemPt.X, ItemPt.Y) .RotateTransform(ItemAngle) '.RotateTransform(-ItemAngle) .FillPolygon(B1, vT1) .DrawPolygon(Pens.Black, vT1) .FillPolygon(B1, vT2) .DrawPolygon(Pens.Black, vT2) .FillPie(B1, r2, aIni, aAmp) .DrawPie(Pens.Black, r2, aIni, aAmp) .DrawLine(Pens.Black, t3, t6) .ResetTransform() B1.Dispose() End With End Sub End Class Public Class clsItem Public Property ItemType As Integer = 0 Public Property Color As Color = Nothing Public Property Pt As Point = Nothing Public Property Angle As Integer = 0 'Public Property Scale As Integer = 0 'Etc... Public Sub New(newType As Integer, newColor As Color, newPt As Point, newAngle As Integer) ItemType = newType Color = newColor Pt = newPt Angle = newAngle End Sub End Class
Attached Images
File Type: png ValveDraw2.png (37.2 KB, 11 views)
__________________
Burn the land and boil the sea
You can't take the sky from me


~T

Last edited by Gruff; 07-21-2014 at 04:50 PM.
Reply With Quote
  #9  
Old 07-22-2014, 05:08 AM
Rodrigo Mota Rodrigo Mota is offline
Regular
 
Join Date: Apr 2005
Location: Portugal
Posts: 53
Default

Thanks Gruff, I'm going to study your code and come back to you later.
Thank you very much.
Reply With Quote
  #10  
Old 07-22-2014, 10:07 AM
Gruff's Avatar
GruffFunction returning image Gruff is offline
Bald Mountain Survivor

Retired Moderator
* Expert *
 
Join Date: Aug 2003
Location: Oregon, USA - deceased
Posts: 6,440
Default

Not a problem. I guess one important fact to note is that since I used your coordinates for the valve in this sample it will start drawing the valve at the mouse coordinates from the upper left corner of the valve.

Due to position and rotation concerns you will probably want to change your valve coordinates such that 0,0 is in the center of the valve symbol not the upper left corner.

The other advantage to using a list(of clsItem) is that you can add a rectangle that represents the outermost bounds around the valve as another property. You could use this rectangle to determine which valve was selected if you wanted to edit that particular valve symbol. (Move it , Change its Angle, Change its Color, Delete it, Ect...)

You would simply iterate through the list checking each rectangle for the mouse location.

Code:
For each item as clsItem in ItemList ' Bounds would be your new rectangle property. If Item.Bounds.Contains(e.Location) then ' Valve found in list. ' Do something with the selected valve. End If Next

It all depends on your end goals for the program.
__________________
Burn the land and boil the sea
You can't take the sky from me


~T

Last edited by Gruff; 07-22-2014 at 10:19 AM.
Reply With Quote
  #11  
Old 07-26-2014, 05:42 AM
Rodrigo Mota Rodrigo Mota is offline
Regular
 
Join Date: Apr 2005
Location: Portugal
Posts: 53
Default

Hey Gruff, I've studied your approach and I'm trying to implement it to do what I want.
I'm still playing around with it and I'm slowly getting to where I want.
Currently I'm trying to create a class that will handle all the graphics stuff and then go on from there.
Thanks again for your help, if I stumble into more problems (and the odds of that happening are pretty high), I know who I'll bug...

Cheers mate.
Reply With Quote
  #12  
Old 07-26-2014, 11:59 AM
Gruff's Avatar
GruffFunction returning image Gruff is offline
Bald Mountain Survivor

Retired Moderator
* Expert *
 
Join Date: Aug 2003
Location: Oregon, USA - deceased
Posts: 6,440
Default

Well it is VB.NET's approach. Not mine.

Realize what I threw together for you was just a rough idea.
it could be improved in many ways. Perhaps by making the draw sub routine part of a valve class, Using enumerations for the ItemTypes, Etc...

In any case Passel taught me just about everything I know about graphics.
So feel free to hit him up for questions as well.
__________________
Burn the land and boil the sea
You can't take the sky from me


~T
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
Function returning image
Function returning image
Function returning image Function returning image
Function returning image
Function returning image
Function returning image Function returning image Function returning image Function returning image Function returning image Function returning image Function returning image
Function returning image
Function returning image
 
Function returning image
Function returning image
 
-->