Create Image from Graphics - vb.net

In VB.NET, I need to create an Image based on a Graphics object I have. However, there is no method such as Image.fromGraphics() etc. What should I do then?

Try something like this MSDN article states. Essentialy create a Graphics Object from a Bitmap. Then use Graphic methods to do what you need to to the Image and then you can use the Image how you need to. As #Damien_The_Unbeliever stated your Graphics Object is created to enable drawing on another object, it does not have an Image to copy, the object it was created on does.
From above article:
Dim flag As New Bitmap(200, 100)
Dim flagGraphics As Graphics = Graphics.FromImage(flag)
Dim red As Integer = 0
Dim white As Integer = 11
While white <= 100
flagGraphics.FillRectangle(Brushes.Red, 0, red, 200, 10)
flagGraphics.FillRectangle(Brushes.White, 0, white, 200, 10)
red += 20
white += 20
End While
pictureBox1.Image = flag

Have a look at the Graphics.DrawImage method and its overloads.
Here's a snippet from one of the examples that draws an image onto the screen, using a Graphics object from Winform's Paint event:
Private Sub DrawImageRect(ByVal e As PaintEventArgs)
' Create image.
Dim newImage As Image = Image.FromFile("SampImag.jpg")
' Create rectangle for displaying image.
Dim destRect As New Rectangle(100, 100, 450, 150)
' Draw image to screen.
e.Graphics.DrawImage(newImage, destRect)
End Sub

Related

How to rotate an Image inside PictureBox by 20 degrees VB 2015?

Say, i have a PictureBox1 in my Form. That PictureBox have an Image in it, and I want to rotate it. Actually, I've learn how to rotate the image by 90,180,270.... degree. But how can I rotate it by 20 degrees or 45 degrees?
This is what I've learn
PictureBox1.Image.RotateFlip(RotateFlipType.Rotate90FlipNone)
My solution:
Public Function RotateImage(ByRef image As Image, ByVal offset As PointF, ByVal angle As Decimal) As Bitmap
If image Is Nothing Then
Throw New ArgumentNullException("image")
End If
''create a new empty bitmap to hold rotated image
Dim rotatedBmp As Bitmap = New Bitmap(image.Width, image.Height)
'Dim rotatedBmp As Bitmap = New Bitmap(image)
rotatedBmp.SetResolution(image.HorizontalResolution, image.VerticalResolution)
''make a graphics object from the empty bitmap
Dim g As Graphics = Graphics.FromImage(rotatedBmp)
''Put the rotation point in the center of the image
g.TranslateTransform(offset.X, offset.Y)
''rotate the image
g.RotateTransform(angle)
''move the image back
g.TranslateTransform(-offset.X, -offset.Y)
''draw passed in image onto graphics object
'g.DrawImage(image, New PointF(0, 0))
g.DrawImage(image, offset)
Return rotatedBmp
End Function

Capture Snapshot image from video in AxWindowsMediaPlayer in vb.net

I am looking for a function to take a screenshot from an embedded Windows Media Player control in a VB.NET Windows form. I am currently using the following function; it works fine, but the problem is that x and y are different on each screen so it would be better if I could use a function in the AxWindowsMediaPlayer control itself, like .Capture() or a similar method.
Private Function TakeImage(ByVal X As Integer, ByVal Y As Integer, ByVal Width As Integer, ByVal Height As Integer) As Bitmap
Dim Img As New Bitmap(Width, Height)
Dim g As Graphics = Graphics.FromImage(Img)
g.CopyFromScreen(X, Y, 0, 0, Img.Size)
g.Dispose()
Return Img
End Function
Dim bmp As Bitmap = TakeImage(x, y - 20, AxWindowsMediaPlayer1.Width, AxWindowsMediaPlayer1.Height)
bmp.Save("E:\pics\" & i.ToString & ".jpg", Drawing.Imaging.ImageFormat.Jpeg)
You could try Ctl.PointToScreen() to get an absolute screen point for CopyFromScreen.
I would get the AxWMP.PointToScreen in the procedure each time since the form could move. Pass them to CopyFromScreen and see if that works. I am not sure if it expects X,Y relative to the app, form or what but Screen, does mean screen.

VB.NET Cartesian Coordinate System

I'd like to make a Cartesian Coordinate System in a Windows form and be able to plot (x,y) coordinates in it.
How do i do this? I already did my research but unfortunately i only land on "charts" and not the Cartesian plane.
Any links regarding my problem will help ... thanks ...
In WinForms, you can use a PictureBox control and then draw on it using primitives such as DrawLine, DrawEllipse, etc. The following SO question contains an example:
how to draw drawings in picture box
In WPF, you can use a Canvas control similarly:
WPF canvas drawing with Graphics
If you want automatic axes and labeling, Charts are indeed the way to go. For your use case, a point chart seems like the right solution:
Point Chart (Chart Controls)
You should create a custom UserControl and use the Paint even to draw on the surface of the control. The Paint event provides you with a Graphics object which you can use to draw the graph. The big thing to know, however, is that you will need to swap your Y axis. In windows, the top-left of the screen is 0,0 rather than the bottom-left.
So, for instance, the following code will draw the x and y axis of a graph on a contorl:
Public Class CartesianGraph
Public Property BottomLeftExtent() As Point
Get
Return _bottomLeftExtent
End Get
Set(ByVal value As Point)
_bottomLeftExtent = value
End Set
End Property
Private _bottomLeftExtent As Point = New Point(-100, -100)
Public Property TopRightExtent() As Point
Get
Return _topRightExtent
End Get
Set(ByVal value As Point)
_topRightExtent = value
End Set
End Property
Private _topRightExtent As Point = New Point(100, 100)
Private Sub CartesianGraph_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim extentHeight As Integer = _topRightExtent.Y - _bottomLeftExtent.Y
Dim extentWidth As Integer = _topRightExtent.X - _bottomLeftExtent.X
If (extentHeight <> 0) And (extentWidth <> 0) Then
If (_bottomLeftExtent.Y <= 0) And (_topRightExtent.Y >= 0) Then
Dim xAxis As Integer = e.ClipRectangle.Height - (_bottomLeftExtent.Y * -1 * e.ClipRectangle.Height \ extentHeight)
e.Graphics.DrawLine(New Pen(ForeColor), 0, xAxis, e.ClipRectangle.Width, xAxis)
End If
If (_bottomLeftExtent.X <= 0) And (_topRightExtent.X >= 0) Then
Dim yAxis As Integer = e.ClipRectangle.Width * _bottomLeftExtent.X * -1 \ extentWidth
e.Graphics.DrawLine(New Pen(ForeColor), yAxis, 0, yAxis, e.ClipRectangle.Height)
End If
End If
End Sub
End Class
.NET has a charting library, but there are a few open source projects that do this sort of thing quite well. If you want to plot coordinates Zedgraph makes this relatively easy and is quite flexible.
this ZedGraph Example gives a great introduction
Dynamic Data Display is also worth looking at, but it is WPF, not Windows Forms

Invert or Flip Text in RDLC report

Okay, I've learned a bit more and have rephrased my question. I've got a need to flip or invert text 180 degrees (so it appears upside-down) on a RDLC report. I have some custom VB code that takes the text, converts it to a bitmap, then flips the rotates the canvas 180 degrees. The effect of this makes the text look a bit.. dithered... or fuzzy. It's not a sharp font anymore. The problem I'm experiencing is I'm using a special TTF Barcode font that creates something a scanner can read. When I flip the barcode font, the fuzziness isn't good since the barcode lines are so close together and the scanner cannot read it. Here's the code:
Function LoadImage(ByVal sImageText as String, iRotationAngle as Integer, ByVal sFontName as String, iFontSize as Integer)
Dim bmpImage As New Drawing.Bitmap(1, 1)
Dim iWidth As Integer = 0
Dim iHeight As Integer = 0
'// Create the Font object for the image text drawing.
Dim MyFont As New Drawing.Font(sFontName, iFontSize) ', System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point)
'// Create a graphics object to measure the text's width and height.
Dim MyGraphics As Drawing.Graphics = Drawing.Graphics.FromImage(bmpImage)
'// This is where the bitmap size is determined.
iWidth = MyGraphics.MeasureString(sImageText, MyFont).Width
iHeight = MyGraphics.MeasureString(sImageText, MyFont).Height
'// Create the bmpImage again with the correct size for the text and font.
bmpImage = New Drawing.Bitmap(bmpImage, New Drawing.Size(iWidth, iHeight))
'// Add the colors to the new bitmap.
MyGraphics = Drawing.Graphics.FromImage(bmpImage)
MyGraphics.Clear(Drawing.Color.White)
MyGraphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
MyGraphics.TranslateTransform(iWidth,iHeight)
MyGraphics.RotateTransform(iRotationAngle)
MyGraphics.DrawString(sImageText, MyFont, New Drawing.SolidBrush(Drawing.Color.Black), 0, 0)
MyGraphics.Flush()
Dim stream As IO.MemoryStream = New IO.MemoryStream
Dim bitmapBytes As Byte()
'Create bitmap
bmpImage.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp)
bitmapBytes = stream.ToArray
stream.Close()
bmpImage.Dispose()
Return bitmapBytes
End Function
I really don't know why there's not a built-in way to just flip text. It'll let me reverse it left-to-right. Ridiculous.
Thanks

Get Font Width within VB.net Without Measuring a Control?

I need to display a table in rich text within a form window. It is only a two column table, so tabbing works fine to line everything up (since RichTextBox does not support RTF tables). However, sometimes the tab stops are incorrect because of non-fixed width fonts.
So, I need a way to measure the pixel width of a particular string with a particular font (Arial 10) and space or tab pad to make sure that everything aligns.
I know about the Graphics.MeaureString method, but since this is in a rich text box, I don't have an initilzed PaintEventArgs variable, and that would seem like overkill to create JUST to measure one string.
From MSDN:
Private Sub MeasureStringMin(ByVal e As PaintEventArgs)
' Set up string.
Dim measureString As String = "Measure String"
Dim stringFont As New Font("Arial", 16)
' Measure string.
Dim stringSize As New SizeF
stringSize = e.Graphics.MeasureString(measureString, stringFont)
' Draw rectangle representing size of string.
e.Graphics.DrawRectangle(New Pen(Color.Red, 1), 0.0F, 0.0F, _
stringSize.Width, stringSize.Height)
' Draw string to screen.
e.Graphics.DrawString(measureString, stringFont, Brushes.Black, _
New PointF(0, 0))
End Sub
So is the best bet just to create a dummy PaintEventArgs instance? If so, what is the best way to do that (since I'll have to call this string measuring method several hundred times)?
Also, I don't really want to have to use a fixed width font - they just don't look as good.
Use this
Dim g as Graphics = richbox.CreateGraphics()
Dim sz as SizeF = g.MeasureString(...)