JohnWein

If would like to use the formating capabilites of a label control to prepare an image for display. I have 3 labels. I want to put a formated number in 2 of the labels and a dash in the other label. I would like to then copy one number label to another image, then copy the dash and then copy the other number. I don't want to display the labels, just the final image ( which is a picturebox.image ) .

Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

jo0ls

Yes you could do it, using Control.DrawToBitmap. You would need 4 bitmaps, one for each control to draw into, and one to draw those 3 bitmaps into. So that would be 3 calls to control.DrawToBitmap, and then 3 call to Graphics.DrawImage. It's a clunky way to do things.

Just use 1 bitmap and a few calls ot Graphics.DrawString, or use the TextRenderer.

Dim bm As New Bitmap(100, 100)

Dim g As Graphics = Graphics.FromImage(bm)

' Draw "Hello World" into the bitmap, centered horizonally and vertically.

TextRenderer.DrawText(g, "Hello World", New Font("Arial", 10), New Rectangle(0, 0, 100, 100), Color.Black, TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter)

g.Dispose()

Me.PictureBox1.Image = bm





Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

SJWhiteley

What formatting capabilities does a Label give you that you can't do by drawing text I would have thought it'd be the other way around...




Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

JohnWein

Drawing gives more capabilities, but requires code. I can align text in a label and set it's background color with no code.

I want to list a number and then a dash and then another number, for example:

"1234 - 5678"

The numbers can vary in length, but I want the dash to always occur at the same location. The background color can be red or lime (green in VB6) for each set of numbers.

The answer to my question I think is: control.drawtobitmap





Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

JohnWein

Yes.  DrawToBitmap was what I was looking for.  I don't know how I missed it.

This is the code that does what I wanted to do.  I'm sure it would have taken me much longer to code if I used the drawing route.  The difficult part using drawing is locating the dash, and spacing the numbers equidistant from the dash.

Public Class Form1

  Private Sub Form1_Load(ByVal sender As Object, _

 ByVal e As System.EventArgs) _

 Handles Me.Load

    PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)

    DrawLbl(0, 999999, Color.Lime, 0)

  End Sub

  Sub DrawLbl(ByVal Txt1 As String, ByVal txt2 As String, _

              ByVal C As Color, ByVal H As Integer)

    Label1.Text = Txt1

    Label3.Text = txt2

    Label1.BackColor = C

    Label2.BackColor = C

    Label3.BackColor = C

    Dim H1 As Integer = H + Label1.Height

    Dim R As Rectangle = New Rectangle(0, H, Label1.Width, H1)

    Label1.DrawToBitmap(PictureBox1.Image, R)

    R = New Rectangle(R.Width, H, Label2.Width, H1)

    Label2.DrawToBitmap(PictureBox1.Image, R)

    R = New Rectangle(R.Left + R.Width, H, Label3.Width, H1)

    Label3.DrawToBitmap(PictureBox1.Image, R)

    PictureBox1.Invalidate()

  End Sub

End Class

 





Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

SJWhiteley

If you say so......kind of round-the-houses...




Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

JohnWein

I'm certainly open for suggestions. I don't see a quicker way to get the job done. I code for my personal use. If I was coding for profit I would code in C++. Can you show me simpler code



Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

jo0ls

If you use TextRenderer.MeasureString then you can work out where things should fit in the bitmap.

Public Class Form1

Private labelFont As New Font("Arial", 12)

Private foreCol As Color = Color.DarkBlue

Private backCol As Color = Color.LightGoldenrodYellow

Private rand As New Random

Private WithEvents t As New Timer

Sub New()

InitializeComponent()

t.Interval = 300

t.Start()

End Sub

Function MakeLabel(ByVal val1 As Integer, ByVal val2 As Integer) As Bitmap

Dim labelText As String = val1 & " - " & val2

Dim bm As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)

Dim g As Graphics = Graphics.FromImage(bm)

g.Clear(backCol)

' Measure the size of the val1, then we can work out how far back from the

' midline to start.

Dim Val1Size As SizeF = TextRenderer.MeasureText( val1.ToString & " ", labelFont)

' Calculate the offest.

Dim offset As Single = bm.Width \ 2 - Val1Size.Width

' Draw into this rectangle:

Dim rec As New Rectangle(offset, 0, bm.Width / 2 + Val1Size.Width, bm.Height)

' Draw the string

TextRenderer.DrawText(g, labelText, labelFont, rec, foreCol, backCol, TextFormatFlags.VerticalCenter)

g.Dispose()

Return bm

End Function

Private Sub t_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles t.Tick

' keep memory usage down by disposing of the old image...

If Me.PictureBox1.Image IsNot Nothing Then

Me.PictureBox1.Image.Dispose()

Me.PictureBox1.Image = Nothing

End If

Me.PictureBox1.Image = MakeLabel(RandNum, RandNum)

End Sub

' create random number for the display.

' This will create more varying lengths than a

' straight rand.next(0,999999999) or something...

Private Function RandNum() As Integer

Dim numberOfDigits As Integer = rand.Next(1, 10)

Dim sb As New System.Text.StringBuilder

For i As Integer = 1 To numberOfDigits

sb.Append(rand.Next(0, 10))

Next

Return Integer.Parse(sb.ToString)

End Function

End Class



Edit: never mind, I see the colors vary too. It can still be done, and isn't too hard when you know some GDI+.





Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

JohnWein

HaHa! Not as easy as it seems at first glance is it



Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

JohnWein

On second thought.  Drawing is simpler.

Private Sub DrawTxt(ByVal I As Integer, ByVal C As Integer)

    Dim G As Graphics = Graphics.FromImage(CutLbl(I))

    G.FillRectangle(LblBrush(C), 0, 0, CutLbl(I).Width, H)

    Dim H2 As Integer = H >> 1

    Dim H4 As Integer = H2 >> 1

    Dim W2 As Integer = CutLbl(I).Width >> 1

    G.DrawLine(Pens.Black, W2 - H4, H2, W2 + H4, H2)

    G.DrawString(CutLst(0, I), CutGrp.Font, Brushes.Black, _

                 W2 - H2 - G.MeasureString(CutLst(0, I), _

                 CutGrp.Font).Width, -1)

    G.DrawString(CutLst(1, I), CutGrp.Font, Brushes.Black, W2 + H2, -1)

    G.Dispose()

  End Sub

 

  Private Sub DrawLbl(ByVal I As Integer, ByVal J As Integer)

    Dim G As Graphics = Graphics.FromImage(CutPic.Image)

    G.DrawImage(CutLbl(I), 0, J * H)

    G.Dispose()

    CutPic.Invalidate

  End Sub

 





Re: Visual Basic Express Edition Copy a control's displayed picture to it's image?

SJWhiteley

Really, whatever works for you. . There are pros and cons to both...

Labels and blitting (copying bitmaps):

Pros: Simplicity. Fewer lines of actual coding. Graphical 'control' over the size of the copied images.

Cons: Non-portability. More difficult to troubleshoot. Sucseptable to end-user interference (since they are labels, they may be changed when the windows sceme changes). Problems with printing.

Manual Drawing:

Pros: portability (the whole thing can be wrapped in a single class or function). Can be printable. Nice fancies can be added effects like transparency, borders, shading, etc.

Cons: more code to write.

What I'd do is first write a prototype function passing all the parameters needed: two numbers, a location for the 'dash', a graphics object, background color: basically the ONLY things you'd need to draw what you want.

Describe what the function is designed to do in either a comment (right click...) or as remarks.

Then list the tasks needed in that function - again, as remarks.

Re-evaluate the function prototype. Ensure that you don't need any external controls, variables, etc.

This is kind of a 'design pattern' I use for building simple routines - things are never simple...as we can see from this thread .