Bind a PictureBox to DataColum in VB.NET - vb.net

I have a data repeater that contains a PictureBox and the picture needs to be fetched from a webserver. I already have a function that downloads the image, but the binding does not seem to be working. I am quite new to using windows forms and I am not too sure what I am doing wrong.
I have tried using a gridview, and I can confirm that that does show the images.
Public Function DlImg(ByVal _URL As String) As Byte()
Dim _tmpImage As Image = Nothing
Dim BytesOut As Byte()
Try
Dim _HttpWebRequest As System.Net.HttpWebRequest = DirectCast(System.Net.HttpWebRequest.Create(_URL), System.Net.HttpWebRequest)
_HttpWebRequest.AllowWriteStreamBuffering = True
Dim _WebResponse As System.Net.WebResponse = _HttpWebRequest.GetResponse():
Dim _WebStream As System.IO.Stream = _WebResponse.GetResponseStream()
_tmpImage = Image.FromStream(_WebStream)
_WebResponse.Close()
Using picture As Image = _tmpImage
Using stream As New IO.MemoryStream
picture.Save(stream, Imaging.ImageFormat.Jpeg)
BytesOut = stream.GetBuffer()
End Using
End Using
Catch _Exception As Exception
Return Nothing
End Try
Return BytesOut
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ListData.Columns.Add("Image", Type.GetType("System.Byte[]"))
For Each row As DataRow In ListData.Rows
row("Image") = DlImg("http://rental.joshblease.co.uk/propertyimages/p184js94kv1qco1e1e1jt71ouv11lm6.jpg")
Next row
ImgListItem.DataBindings.Add("Image", ListData, "Image", True)
DataGridView1.DataSource = ListData
DataRepeater1.DataSource = ListData
End Sub

Related

Get Image from SQL using Listbox to picturebox VB

i'm trying to get the image from SQL to picturebox using Listbox in in VB.
here is my sql sample table.
and here is my VB Design form, so what I'm trying to do is when I load the form, if an item in the listbox is selected, i want it to get the image(Binary Data) from sql to picturebox in vb net.
and the code I'm working with it give me this error:
VB full code:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
connect()
Dim co As New SqlConnection("Data Source=WXCQSDQSD\SQLEXPRESS;Initial Catalog=food;Integrated Security = True")
co.Open()
Dim com As New SqlCommand("SELECT Image from Items where ItemName = '" & ListBox1.SelectedIndex & "'", co)
Dim img As Byte() = DirectCast(com.ExecuteScalar(), Byte())
Dim ms As MemoryStream = New MemoryStream(img)
Dim dt = GetDataFromSql()
Dim BndSrc As New BindingSource()
BndSrc.DataSource = dt
ListBox1.DisplayMember = "ItemName"
ListBox1.DataSource = BndSrc
TextBox1.DataBindings.Add("Text", BndSrc, "ItemID")
TextBox2.DataBindings.Add("Text", BndSrc, "ItemName")
TextBox3.DataBindings.Add("Text", BndSrc, "Details")
PictureBox1.Image = Image.FromStream(ms)
End Sub
Private Function GetDataFromSql() As DataTable
Dim dt As New DataTable
Using connection As New SqlConnection("Data Source=WXCQSDQSD\SQLEXPRESS;Initial Catalog=food;Integrated Security = True"),
cmd As New SqlCommand("select * FROM Items", connection)
connection.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
Remove the picture retrieval from the Form.Load. We have selected all the data in the GetDataFromSql function. The magic happens in the ListBox1.SelectedIndexChanged method.
The SelectedIndexChanged will occur as a result of the code in the Form.Load and every time the selection changes. When we bind the the list box to to binding source the entire row is added as a DataRowView. We can use this to get the data in the Image column. First check if the field is null. Next cast to a byte array. Take the byte array and pass it to the constructor of a MemoryStream. Streams need to be disposed so it is in a Using block. Finally the stream can be assigned to the Image property of the PictureBox.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt = GetDataFromSql()
Dim BndSrc As New BindingSource()
BndSrc.DataSource = dt
ListBox1.DisplayMember = "ItemName"
ListBox1.DataSource = BndSrc
TextBox1.DataBindings.Add("Text", BndSrc, "ItemID")
TextBox2.DataBindings.Add("Text", BndSrc, "ItemName")
TextBox3.DataBindings.Add("Text", BndSrc, "Details")
End Sub
Private Function GetDataFromSql() As DataTable
Dim dt As New DataTable
Using connection As New SqlConnection("Data Source=WXCQSDQSD\SQLEXPRESS;Initial Catalog=food;Integrated Security = True"),
cmd As New SqlCommand("select * FROM Items", connection)
connection.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim row = DirectCast(ListBox1.SelectedItem, DataRowView)
If row("Image") IsNot Nothing Then
Dim b() As Byte = DirectCast(row("Image"), Byte()) '< ------ Cast the field to a Byte array.
Using ms As New System.IO.MemoryStream(b)
PictureBox1.Image = System.Drawing.Image.FromStream(ms)
End Using
Else
PictureBox1.Image = Nothing
End If
End Sub
EDIT
I switched the code over to a database I have available for testing. Even though it is not your database, I am sure you will be able to follow the code.
Here is the schema of my database.
The main difference is I moved the DataTable to a class level variable so it can be seen from all methods. I changed the GetDataFromSql to a Sub. It adds the data to the class level DataTable (Bounddt). The AddItem method first gets the Byte() from a file. The row is added to the DataTable with an Object array with elements that match the DataTable.
Private Bounddt As New DataTable
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
GetDataFromSql()
Dim BndSrc As New BindingSource()
BndSrc.DataSource = Bounddt
ListBox1.DisplayMember = "CustomerID"
ListBox1.DataSource = BndSrc
TextBox1.DataBindings.Add("Text", BndSrc, "CustomerID")
TextBox2.DataBindings.Add("Text", BndSrc, "CustomerName")
End Sub
Private Sub GetDataFromSql()
Using connection As New SqlConnection("Data Source=****;Initial Catalog='Small Database';Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"),
cmd As New SqlCommand("select * FROM Sales.Customer", connection)
connection.Open()
Using reader = cmd.ExecuteReader
Bounddt.Load(reader)
End Using
End Using
'Return dt
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim row = DirectCast(ListBox1.SelectedItem, DataRowView)
If row("Picture") IsNot Nothing Then
Dim b() As Byte = DirectCast(row("Picture"), Byte()) '< ------ Cast the field to a Byte array.
Using ms As New System.IO.MemoryStream(b)
PictureBox1.Image = System.Drawing.Image.FromStream(ms)
End Using
Else
PictureBox1.Image = Nothing
End If
End Sub
Private Sub AddItem()
Dim picture = GetByteArr("C:\Users\maryo\OneDrive\Documents\Graphics\Animals\squirrel.png")
Bounddt.Rows.Add({5, "George", 74, 62, "George", picture})
End Sub
Private Function GetByteArr(path As String) As Byte()
Dim img = Image.FromFile(path)
Dim arr As Byte()
Dim imgFor As Imaging.ImageFormat
Dim extension = path.Substring(path.LastIndexOf(".") + 1)
'There is a longer list of formats available in ImageFormat
Select Case extension
Case "png"
imgFor = Imaging.ImageFormat.Png
Case "jpg", "jpeg"
imgFor = Imaging.ImageFormat.Jpeg
Case "bmp"
imgFor = Imaging.ImageFormat.Bmp
Case Else
MessageBox.Show("Not a valid image format")
Return Nothing
End Select
Using ms As New MemoryStream
img.Save(ms, imgFor)
arr = ms.ToArray
End Using
Return arr
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddItem()
End Sub
Imports System.Data.SqlClient
Imports System.IO
Public Class Form1
Dim con As SqlConnection
Dim cmd As SqlCommand
Dim rdr As SqlDataReader
Dim da As SqlDataAdapter
Private Const cs As String = "ConnectionString"
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
con = New SqlConnection(cs)
con.Open()
cmd = New SqlCommand("select * from [dbo].[Item_Details]", con)
rdr = cmd.ExecuteReader()
While rdr.Read
ListBox1.Items.Add(rdr(1))
End While
con.Close()
End Sub
Private Sub ListBox1_MouseClick(sender As Object, e As MouseEventArgs) Handles ListBox1.MouseClick
Try
con = New SqlConnection(cs)
con.Open()
da = New SqlDataAdapter("Select * from Item_Details where itemname='" & ListBox1.SelectedItem.ToString() & "'", con)
Dim dt As New DataTable
da.Fill(dt)
For Each row As DataRow In dt.Rows
TextBox1.Text = row(0).ToString()
TextBox2.Text = row(1).ToString()
TextBox3.Text = row(2).ToString()
Dim data As Byte() = row(3)
Dim ms As New MemoryStream(data)
PictureBox1.Image = Image.FromStream(ms)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class

Visual basic Windows forms BitArray convert to string

Hi I made a code and it outputs random characters and unknown symbols.
The code is:
Function ReceiveMessages() As String
Dim receiveBytes As [Byte]() = receivingUdpClient.Receive(RemoteIpEndPoint)
from = RemoteIpEndPoint.Address.ToString
Dim BitDet As BitArray
BitDet = New BitArray(receiveBytes)
Dim strReturnData As String = _
System.Text.Encoding.Unicode.GetString(receiveBytes)
rt = strReturnData
I don't think it is a problem with the receiving but it might.
This function is called by:
Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
Try
receivingUdpClient = New System.Net.Sockets.UdpClient(11211)
Catch ex As Exception
End Try
ThreadReceive = _
New System.Threading.Thread(AddressOf ReceiveMessages)
ThreadReceive.Start()
End Sub
If you could help I would appreciate it.

For Next or a different loop for URL Icon Load

I have an app that basically is a launcher for various web pages. I am trying to, OnLoad, to populate all the pictureBoxes in my form with the FavICON for each URL. 25 to be exact. Should I use a For and Next or some other kind of looping method? New to the looping part so all and any help is appreciated.
My code to load just one single PictureBox is the following:
Private Sub MainFormWPL_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Dim WebICON As New WebBrowser
MainURLLoader.Navigate(Label1.Text)
'URLText.Text = WebBrowser1.Url.ToString
Try
Dim url As Uri = New Uri(Label1.Text)
If url.HostNameType = UriHostNameType.Dns Then
Dim icon = "http://" & url.Host & "/favicon.ico"
Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(icon)
Dim response As System.Net.HttpWebResponse = request.GetResponse()
Dim stream As System.IO.Stream = response.GetResponseStream
Dim favicon = Image.FromStream(stream)
PictureBox1.Image = favicon
Else
End If
Catch ex As Exception
End Try
End Sub
Assuming you have Label1 --> PictureBox1, all the way to Label25 --> PictureBox25:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim matches() As Control
For i As Integer = 1 To 25
matches = Me.Controls.Find("Label" & i, True)
If matches.Length > 0 Then
Dim website As String = matches(0).Text
matches = Me.Controls.Find("PictureBox" & i, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is PictureBox Then
Dim PB As PictureBox = DirectCast(matches(0), PictureBox)
Task.Run(New Action(Sub() GetFavIcon(website, PB)))
End If
End If
Next
End Sub
Private Sub GetFavIcon(ByVal website As String, ByVal PB As PictureBox)
Dim url As Uri = New Uri(website)
If url.HostNameType = UriHostNameType.Dns Then
Dim icon = "http://" & url.Host & "/favicon.ico"
Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(icon)
Dim response As System.Net.HttpWebResponse = request.GetResponse()
Dim stream As System.IO.Stream = response.GetResponseStream
Dim favicon = Image.FromStream(stream)
PB.Invoke(New MethodInvoker(Sub() PB.Image = favicon))
response.Close()
End If
End Sub
End Class

Display Metadata-thumbnail of Jpeg in picturebox

I need to display a Image's thumbnail, that is saved in its Metadata in a picturebox. I'm using VB.NET
http://msdn.microsoft.com/en-us/library/windows/desktop/ee719904%28v=vs.85%29.aspx#_jpeg_metadata
So far i came up with this. Adding a breakpoint displays that GETQUERY returns empty even if i know that the file does indeed have a thumbnail
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim imagepath = "C:\xampp\htdocs\Downloads\IMG_1322.JPG" ' path to file
Dim stream = New FileStream(imagepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
Dim decoder = New JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.None)
Dim metadata = TryCast(decoder.Frames(0).Metadata, BitmapMetadata)
Dim ms As New System.IO.MemoryStream
Dim bm As Bitmap
Dim arData() As Byte
arData = metadata.GetQuery("/app0/{ushort=6}") '<--- Breakpoint here: Query returns nothing!
ms.Write(arData, 78, arData.Length - 78)
bm = New Bitmap(ms)
PictureBox1.Image = bm
stream.Close()
End Sub
You can try something like this:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim imagepath = "C:\xampp\htdocs\Downloads\IMG_1322.JPG" ' path to file
Dim stream = New FileStream(imagepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
Dim decoder = New JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.None)
Dim metadata = TryCast(decoder.Frames(0).Metadata, BitmapMetadata)
Dim thumb As BitmapMetadataBlob
thumb = metadata.GetQuery("/app1/thumb/")
If Not (thumb Is Nothing) Then
Dim src As New BitmapImage
Dim ms As MemoryStream = New MemoryStream(thumb.GetBlobValue())
src.BeginInit()
src.StreamSource = ms
src.EndInit()
PictureBox1.Source = src
End If
stream.Close()
End Sub

vb.net sending file over TCP

I know similar questions like this have been asked on various forums, however none of the given solutions have worked for me, and was wondering if anyone had any other pointers they could give. I am basically trying to send a file (an image) over TCP between 2 computers on the same network. I have been trying to convert the image to a byte array, then to a string before sending the string. On the other side, I have received the string, converted to a byte array, and then convert back to an image. However, on the receiving side, the string is empty so I am getting an error when I then convert that to a byte array.
The code for the sending side is:
Private Sub startSending()
Dim ScreenShot As Image = sc.CaptureScreen
Dim path As String = My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData + "\redsquirimgtest"
sc.CaptureScreenToFile(path, System.Drawing.Imaging.ImageFormat.Jpeg)
MsgBox("printscreen saved")
Dim abyt() As Byte = ConvertImageFiletoBytes(path)
MsgBox("image converted to byte array")
Dim str As String = byteArrToString(abyt)
MsgBox(str)
client.Connect("192.168.1.10", 55000)
Dim Writer As New StreamWriter(client.GetStream())
Writer.Write(str)
Writer.Flush()
MsgBox("sent")
Form2.PictureBox1.Image = ScreenShot
Form2.Show()
MsgBox("done")
End Sub
Public Function ConvertImageFiletoBytes(ByVal ImageFilePath As String) As Byte()
Dim _tempByte() As Byte = Nothing
If String.IsNullOrEmpty(ImageFilePath) = True Then
Throw New ArgumentNullException("Image File Name Cannot be Null or Empty", "ImageFilePath")
Return Nothing
End If
Try
Dim _fileInfo As New IO.FileInfo(ImageFilePath)
Dim _NumBytes As Long = _fileInfo.Length
Dim _FStream As New IO.FileStream(ImageFilePath, IO.FileMode.Open, IO.FileAccess.Read)
Dim _BinaryReader As New IO.BinaryReader(_FStream)
_tempByte = _BinaryReader.ReadBytes(Convert.ToInt32(_NumBytes))
_fileInfo = Nothing
_NumBytes = 0
_FStream.Close()
_FStream.Dispose()
_BinaryReader.Close()
Return _tempByte
Catch ex As Exception
Return Nothing
End Try
End Function
Public Function byteArrToString(ByVal arr() As Byte) As String
Return System.Text.Encoding.Unicode.GetString(arr)
End Function
And then the receiving side:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
' Check the TcpListner Pending Property
If TcpListener.Pending = True Then
Dim Message As String = ""
ConnectClient = TcpListener.AcceptTcpClient()
MsgBox("accepting")
Dim Reader As New StreamReader(ConnectClient.GetStream())
While Reader.Peek > -1
Message = Message + Reader.Read().ToString
End While
MsgBox(Message)
Dim abyt() As Byte = StrToByteArray(Message)
MsgBox("string converted to byte array")
Dim img As Image = ConvertBytesToImageFile(abyt)
MsgBox("byte array converted to image")
PictureBox1.Image = img
MsgBox("picture loaded in form")
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
TcpListener.Start()
End Sub
Public Function ConvertBytesToImageFile(ByVal ImageData As Byte()) As Image
Dim myImage As Image
Dim ms As System.IO.Stream = New System.IO.MemoryStream(ImageData)
myImage = System.Drawing.Image.FromStream(ms)
Return myImage
End Function
Public Shared Function StrToByteArray(str As String) As Byte()
Return System.Text.Encoding.Unicode.GetBytes(str)
End Function
Thanks in advance for any help you can give!
Not sure if is the necessarily problem here, but I would suggest converting the bytes to string using System.Convert.ToBase64String(byte_array)
This will always give a safe string with no awkward characters which can be transmitted in various ways.
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
' Check the TcpListner Pending Property
If TcpListener.Pending = True Then
Dim Message As String = ""
ConnectClient = TcpListener.AcceptTcpClient()
MsgBox("accepting")
Dim Reader As New StreamReader(ConnectClient.GetStream())
While Reader.Peek > -1
Message = Message + Reader.Read().ToString
End While
MsgBox(Message)
Dim abyt() As Byte = StrToByteArray(Message)
MsgBox("string converted to byte array")
Dim img As Image = ConvertBytesToImageFile(abyt)
MsgBox("byte array converted to image")
PictureBox1.Image = img
MsgBox("picture loaded in form")
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
TcpListener.Start()
End Sub
Public Function ConvertBytesToImageFile(ByVal ImageData As Byte()) As Image
Dim myImage As Image
Dim ms As System.IO.Stream = New System.IO.MemoryStream(ImageData)
myImage = System.Drawing.Image.FromStream(ms)
Return myImage
End Function
Public Shared Function StrToByteArray(str As String) As Byte()
Return System.Text.Encoding.Unicode.GetBytes(str)
End Function
sc.CaptureScreen
sc.CaptureScreenToFile(path, System.Drawing.Imaging.ImageFormat.Jpeg)
sc. <-- ist nicht deklariert ERROR