vb.net how to convert picturebox to bitmap - vb.net

I want pixel color value of the picturebox
I assigned text to the picturebox & now want to get the value of color of each pixel
What is method of picturebox or i should convert it to bitmap? How?
in vb6 there is getpixel() method to get color value
What is in .net?

If you can convert it into a bitmap, it's a breeze:
Dim MyBitmap As New Bitmap(MyPicturebox.Image)
Dim MyColor As Color
MyColor = MyBitmap.GetPixel(X of your pixel, Y of your pixel)
You might want to loop through the pixels, which is not hard if you know the width and height.

Related

Get the position where drawn text is truncated by GraphicsPath.DrawString

I have a couple of methods that draw outlined text. The details of this are unimportant, but it serves to illustrate the problem:
(source code from Graphics DrawPath produces unexpected results when rendering text)
Private Sub FillTextSolid(g As Graphics, bounds As RectangleF, text As String, font As Font, fillColor As Color, sf As StringFormat)
Using gp As GraphicsPath = New GraphicsPath(),
brush As New SolidBrush(fillColor)
gp.AddString(text, font.FontFamily, font.Style, font.Size, bounds, sf)
g.FillPath(brush, gp)
End Using
End Sub
correctly converts a long string into one with an ellipsis inside the bounds. E.g.
Manic Miner is a platform video game originally written for the ZX
Spectrum by Matthew Smith and released by Bug-Byte in 1983. It is the
first game in the Miner Willy series and among the early titles in the
platform game genre.
becomes:
Manic Miner is a platform video game originally written for the ZX
Spectrum by Matthew Smith and released by Bug-Byte in 1983. It is the
first game in the Miner...
All well and good. What I need is a way in code to see exactly what part of the full text has been displayed. This will then be used to cycle through the text in the same bounds (almost paging if you will) to display all the text.
I looked at MeasureString but this didn't seem to achieve this. Is there any way I can discern this? In pseudo code, something like:
Dim textShown as string = gp.AddString(text, font.FontFamily, font.Style, font.Size, bounds, sf).TextShown
Thanks
Given the FillTextSolid() method shown before in:
Graphics DrawPath produces unexpected results when rendering text
Private Sub FillTextSolid(g As Graphics, bounds As RectangleF, text As String, font As Font, fillColor As Color)
Using gp As GraphicsPath = New GraphicsPath(),
brush As New SolidBrush(fillColor),
format = New StringFormat(StringFormat.GenericTypographic)
format.Trimming = StringTrimming.EllipsisWord
gp.AddString(text, font.FontFamily, font.Style, font.Size, bounds, StringFormat.GenericTypographic)
g.FillPath(brush, gp)
Dim lastCharPosition = GetPathLastCharPosition(g, format, gp, bounds, text, font)
End Using
End Sub
you can use the current GraphicsPath, Rectangle bounds, Font size and style used for drawing the the text in a graphics context, to calculate the position of the last character drawn and, as a consequence, the last word, if necessary.
I've added in FillTextSolid() a call to the GetPathLastCharPosition() method, which is responsible for the calculation. Pass to the method the objects described, as they're currently configured (these settings can of course change at any time: see the animation at the bottom).
Dim [Last Char Position] = GetPathLastCharPosition(
[Graphics],
[StringFormat],
[GraphicsPath],
[RectangleF],
[String],
[Font]
)
To determine the current last word printed using a GraphicsPath object, you cannot split the string in parts separated by, e.g., a white space, since each char is part of the rendering.
Also to note: for the measure to work as intended, you cannot set the drawing Font size in Points, the Font size must be expressed in pixels.
You could also use Point units, but the GraphicsPath class, when Points are specified, generates (correctly) a Font measure in EMs - considering the Font Cell Ascent and Descent - which is not the same as the Font.Height.
You can of course convert the measure from Ems to Pixels, but it just adds complexity for no good reason (in the context of this question, at least).
See a description of these details and how to calculate the GraphicsPath EMs in:
Properly draw text using GraphicsPath
GetPathLastCharPosition() uses Graphics.MeasureCharacterRanges to measure the bounding rectangle of each char in the Text string, in chunks of 32 chars per iteration. This is because StringFormat.SetMeasurableCharacterRanges only takes a maximum of 32 CharacterRange elements.
So, we take the Text in chunks of 32 chars, get the bounding Region of each and verify whether the Region contains the last Point in the GraphicsPath.
The last Point generated by a GraphicsPath is returned by the GraphicsPath.GetLastPoint().
This procedure only considers text drawn from top to bottom and left to right.
It can be adapted to handle right to left languages.
Of course, you could also ignore the last point and just consider whether a Region bounds fall outside the bounding rectangle of the canvas.
Anyway, when the a Region that contains the last point is found, the method stops and returns the position of the last character in the string that is part of the drawing.
Private Function GetPathLastCharPosition(g As Graphics, format As StringFormat, path As GraphicsPath, bounds As RectangleF, text As String, font As Font) As Integer
Dim textLength As Integer = text.Length
Dim p = path.GetLastPoint()
bounds.Height += font.Height
For charPos As Integer = 0 To text.Length - 1 Step 32
Dim count As Integer = Math.Min(textLength - charPos, 32)
Dim charRanges = Enumerable.Range(charPos, count).Select(Function(c) New CharacterRange(c, 1)).ToArray()
format.SetMeasurableCharacterRanges(charRanges)
Dim regions As Region() = g.MeasureCharacterRanges(text, font, bounds, format)
For r As Integer = 0 To regions.Length - 1
If regions(r).IsVisible(p.X, p.Y) Then
Return charRanges(r).First
End If
Next
Next
Return -1
End Function
This is how it works:
C# version of the method:
private int GetPathLastCharPosition(Graphics g, StringFormat format, GraphicsPath path, RectangleF bounds, string text, Font font)
{
int textLength = text.Length;
var p = path.GetLastPoint();
bounds.Height += font.Height;
for (int charPos = 0; charPos < text.Length; charPos += 32) {
int count = Math.Min(textLength - charPos, 32);
var charRanges = Enumerable.Range(charPos, count).Select(c => new CharacterRange(c, 1)).ToArray();
format.SetMeasurableCharacterRanges(charRanges);
Region[] regions = g.MeasureCharacterRanges(text, font, bounds, format);
for (int r = 0; r < regions.Length; r++) {
if (regions[r].IsVisible(p.X, p.Y)) {
return charRanges[r].First;
}
}
}
return -1;
}

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

How to create a matrix with a new List of Color

Basically, what I want to do is this:
Dim colors1(100, 100) As New List(Of Color)
I need to create a matrix with the New List(Of Color).
I will explain better...
I want to read all the colors of the pixels of my image, and usualy i would do that by reading line by line.
But that is not the case.
I divide the image in 8x8 squares and i want create an matrix(whit position of square)and the List(Of Color)(whit the colors of that square) that says all the colors of each square. Infortunaly when i try do this Dim colors1(100,100) as List(Of Color)the program break.
Try this
Dim colors1 As New List(Of List(Of Color))
For i As Integer = 0 To 99
Dim newColors As New List(Of Color)
colors1.Add(newColors)
For j As Integer = 0 To 99
newColors.Add(New Color)
Next
Next​
Well, are you wanting to use an Array or a List for this?
If you want a fixed 100x100 matrix then you should use a 2D Array since arrays are fixed size.
If you're happy to use a fixed 100x100 2D Array, you can declare it like:
Dim colors1(100, 100) As Color
Set it like this:
colors1(5, 2) = Color.Aqua
And then use it like this:
' Sets the textbox background color to Aqua
TextBox1.BackColor = colors1(5, 2)
Does that achieve what you're trying to do? Or did you need the List for another reason?

Create Image from Graphics

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

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(...)