Retrieving images from a database? - sql

I'm new to the forums and wanted to ask a question that has been bugging me for ages. I am using Visual Studio express 2012 with Windows Forms.
I want to have a database consisting of different images. Each row has its own image, and the other fields in the row define the images characteristics (I.E. Colour = Red, Striped = Yes etc) and its own specific ID.
Now what I want to do is allow the user to search via the form (Selecting what characteristics they want the image to have based on options on the form and then using SQL statements to retrieve the images based on their inputs). The only issue I am having is displaying all of the images on the form when they have searched? Is there any idea as to how to do this dynamically?

I created a form with FlowLayoutPanel in it. I set its AutoScroll property to true so that if there more pictures than fit in the space, it'll show a scroll bar so you can see them all.
I'm not entirely sure how you're getting the image, but assuming you have a function that returns a list of images.
Private Function DoImageSearch(parameters As SearchParameters) As List(Of Image)
'Go get images from database
End Function
Then you could have a function like the following to dynamically create PictureBox controls to be added to the FlowLayoutPanel.
Private Sub DynamicallyCreatedPictureBoxes(images As List(Of Image))
For Each image In images
Dim picture = New PictureBox()
picture.Image = image
picture.Size = image.Size
FlowLayoutPanel1.Controls.Add(picture)
Next
End Sub
In this case I've set the size of the PictureBox to be the size of the image. You may want to try to scale them or make thumbnails, but I'll leave that up to you (or another question). You'd probably also want another method to clear the images.
Private Sub ClearPictureBoxes()
FlowLayoutPanel1.SuspendLayout()
For Each control As Control In FlowLayoutPanel1.Controls
control.Dispose()
Next
FlowLayoutPanel1.Controls.Clear()
FlowLayoutPanel1.ResumeLayout()
End Sub
I'm not confident that last method is entirely correct, but you'd probably want something close to it.

Try like the this,
If color_RadioButton.Checked = True and type_RadioButton.Checked = True Then
cmdTect="color='" & color_RadioButton.Text & "' and type='" & type_RadioButton.Text & "'"
ElseIf color_RadioButton.Checked = True and type_RadioButton.Checked = False Then
cmdTect="color='" & color_RadioButton.Text & "'"
ElseIf color_RadioButton.Checked = False and type_RadioButton.Checked = TrueThen
cmdTect="type='" & type_RadioButton.Text & "'"
End If
dim cmd as new sqlcommand("select count(photo) from tbl where " & cmdTect,conn)
dim cnt as integer=cmd.ExecuteScalar()
for i as integer=0 to cnt
cmd = New SqlCommand("select photo from tbl where" & cmdTect,conn)
Dim imageData As Byte() = DirectCast(cmd.ExecuteScalar(), Byte())
If Not imageData Is Nothing Then
Dim ms As New MemoryStream(imageData, 0, imageData.Length)
ms.Write(imageData, 0, imageData.Length)
Dim pic As New PictureBox
pic.BackgroundImage = Image.FromStream(ms, True)
Panel1.Controls.Add(pic)
End If
Next

Related

How can I save an image using System.Drawing.Imaging without auto rotating it?

When I resize my image and save it using the "System.Drawing.Imaging" save function, it adds the rotation embedded from the EXIF data and rotates my good original picture 180 degrees. I tried saving it in a different format to remove the EXIF data but it still includes the EXIF rotation for the new picture. Any ideas on how I can save the picture in the orientation I can see in the thumbnails .
Private Sub ClearEXIF()
Dim Pname As String = Nothing
For Each Fil In Directory.GetFiles(DlDir)
OK2Go = False
If Fil.Contains("jpg") Then OK2Go = True
If Fil.Contains("jpeg") Then OK2Go = True
If OK2Go Then
Dim bmp As Bitmap = Image.FromFile(Fil)
Pname = GetLastName(Fil) 'this function gets the name of the jpg without the path info
temp1 = Split(Pname, ".")
bmp.Save("C:\Temp\Flat\" & temp1(0) & "+" & temp1(1) & ".png", ImageFormat.png)
bmp.Dispose()
End If
Next
MsgBox("Done")
End Sub

Check if data exist in file

I need help. I want to check if user exists by entering their ic number and I want to display another rest of their data by using file in visual basic. Unfortunately, an error occurs while doing that. I need help. If the user exists, then It will display automatically name, email, address and so on but if a user doesn't exist, then it shows message box. Here I attached the image of the display screen and the code. Please help me. Thank you.
Public Class Form1
Private Sub btnSearch_Click(sender As Object, e As EventArgs) Handles btnSearch.Click
Dim userFile As String = "C:\Users\HP\Desktop\userdata.txt"
Dim inputFile As String
If System.IO.File.Exists(userFile) = True Then
Dim objReader As New System.IO.StreamReader(userFile)
Dim intIc As Integer
Dim intCount As Integer = 0
Dim strName As String
Dim strEmail As String
Dim intPhoneNum As String
Dim strAdd1 As String
Dim strAdd2 As String
Dim intPostcode As String
Dim strState As String
Do While objReader.Peek() <> -1
intIc(intCount) = Convert.ToInt64(objReader.ReadLine())
If (intIc(intCount).Convert.ToInt64(objReader.ReadLine())) Then
strName(intCount) = objReader.ReadLine()
strEmail(intCount) = objReader.ReadLine()
intPhoneNum(intCount) = Convert.ToInt32(objReader.ReadLine())
strAdd1(intCount) = objReader.ReadLine()
strAdd2(intCount) = objReader.ReadLine()
intPostcode(intCount) = Convert.ToInt32(objReader.ReadLine())
strState(intCount) = objReader.ReadLine()
lblName.Text = strName
lblEmail.Text = strEmail
lblNum.Text = intPhoneNum
lblAdd1.Text = strAdd1
lblAdd2.Text = strAdd2
lblPostcode.Text = intPostcode
lblState.Text = strState
objReader.Close()
Else
MessageBox.Show("User Does Not Exist")
End If
intCount = intCount + 1
Loop
Else
MessageBox.Show("File Does Not Exist")
End If
End Sub
End Class
Your task, the easy way:
make a new project
add a DataSet to this new project
open the DataSet, in the properties call it something sensible
Right click the surface, add a new datatable, name it Person
Right click the datatable, add a column, name it IC. Right click, add column, name it Name. Keep going until you added all the fields you want to track(email,phone,address1 etc)
save the DataSet
open the form
show the datasources window (view menu.. other windows)
expand the nodes til you can see Person
click the drop down next to Person, switch from DataGridview to Details
drag Person onto the form. Text boxes, labels etc appear. In the tray at the bottom more things appear
add a textbox to the form and call it searchTextBox
add a search button to the form, double click it, add this line of code to the click handler:
personBindingSource.Filter = '[ic] LIKE '" & searchTextBox.Text & "'"
If personBindingSource.Count = 0 Then MessageBox.Show("No records")
double click the form background to add a form load event handler, put this line of code:
If IO.File.Exists("data.xml") Then .ReadXml("data.xml")
switch back to designer, single click the form background and switch to event properties of the form, add a handler to the form closing event:
.WriteXml("data.xml")
That's it, you now have a program that will open, read and fill the DataSet with data from the data.xml file, it will search it when you type something in the ic box, the text boxes use databinding to show values automatically, and when you close the program it will save updates data. The only task now is to load the xml file with data.
When the textboxes were added to the form you should also have seen a bar appear across the top with some left/right controls in and a green plus. Click the green plus, type some data in, click it again, type more data. Navigating back, if you're adding new data, will commit the data. If you're looking at existing data, editing it then navigating will commit it
After you added some data, you can search for existing data using the search box. When you've searched for a single value it should be the only thing shown and the nav will show "1 of 1". To get back to the mode where all data is showing, put a single asterisk in the search box and hit search; it should show the number records in the top bar and you can scroll them with the arrows.
If you already have lots of data in a file, like you use in your question, you can read it in a loop (like you do in your question, except don't use that code exactly cos it has loads of errors) as a one time thing and assign it into the datatable, or you can manipulate it directly into being XML in a text editor. This is easy to do if you have a capable text editor but I'll not offer any particular advice on it in case you don't have a large amount of existing data. Ask a new question if you do

Adding images into next available picturebox

I'm doing a deck builder project through a card database and so far when I click a row (using datagridview), the value contained in the "image_url" column is printed into an invisible textbox, which is then used to download that image and show it in a picturebox.
Now that all works fine, but decks go up to 60 cards so I'm going to use 60 pictureboxes to print the user's selected cards. What I'm been trying to do is set up like a picturecount and when they select a column the number is increased by one like this:
picturebox(picturecount) = textbox4.text
but I've run into too many errors. Would you know a way to display the user's selected card in the next available picturebox? For example if they select "Dark Magician" three times, then the image of the "Dark Magician" is printed in the first available three pictureboxes
VB.NET:
Private Async Sub PictureLoader()
Dim imageURL As String
If TextBox4.Text = "" Then
imageURL = dataSet.Tables("YGO cards").Rows(row_count).Item(7)
Else
imageURL = TextBox4.Text
End If
Dim client As Net.WebClient = New Net.WebClient()
Dim ms As MemoryStream = New MemoryStream(Await client.DownloadDataTaskAsync(New Uri(imageURL)))
Using image As Image = Image.FromStream(ms)
PictureBox1.Image?.Dispose()
PictureBox1.Image = DirectCast(image.Clone(), Image)
End Using
ms.Dispose()
client.Dispose()
End Sub
and this is the event when a column is selected in the datagrid!
Dim index As Integer
index = e.RowIndex
Dim selectedrow As DataGridViewRow
selectedrow = DataGridView1.Rows(index)
' selectedrow.Cells(1) is the image_Url column
TextBox4.Text = selectedrow.Cells(1).Value.ToString()
If TextBox4.Text = "" Then
PictureBox1.Image = Nothing
' imageURL = dataSet.Tables("YGO cards").Rows(row_count).Item(7)
Else
PictureLoader()
End If
Ignore for a moment the specifics of your particular problem and break this down into a generic statement. What you're saying is that you have a collection and that the size of the collection can grow or shrink based on user input. This is an ideal case for a List(Of T) where you declare the List by specifying the data type of the items it will hold and then add items as needed. Because you are storing the URL of the card, you would create a new List(Of String):
Dim cards As List(Of String) = New List(Of String)
Now whenever you needed to add URLs to your list you would call the Add method if it is a single URL or AddRange if it is multiple URLs:
cards.Add(TextBox1.Text)
'Or
cards.AddRange({TextBox1.Text, TextBox2.Text, TextBox3.Text})
As far as displaying the image in the PictureBox, there's really no need to create a MemoryStream and clone an Image considering that the PictureBox class has the Load and LoadAsync (which it looks like you want asynchronous capabilities) methods. But if you wanted to create a PictureBox for every item in your collection, you will need to iterate through the collection, create a new PictureBox, call the Load or Load Async method on the currently iterated URL, and then add it to the Form (or a container in general). This can be done using a traditional For/Each loop:
'Create a placeholder variable
Dim cardPictureBox As PictureBox
'Loop through every selected card URL
For Each url As String In Cards
'Create a new PictureBox
cardPictureBox = New PictureBox() With {
.Size = New Size(100, 100)
.SizeMode = PictureBoxSizeMode.CenterImage
.WaitOnLoad = False
}
'Add the PictureBox to the Form
Me.Controls.Add(cardPictureBox)
'Load the image asynchronously
cardPictureBox.LoadAsync(url)
Next

Passing Parameter to Crystal Reports XI from Visual Studio 2015

I am running into problems with the passing of parameters to an externally created Crystal Reports XI report from the WinForms application I'm building in Visual Studio 2015 Community Edition. No matter what I try to do, the report doesn't seem to get the value unless I manually select it at the prompt (which shouldn't even be popping up) when the report is being displayed. I'm using the same code I've used in a previous application (although that one was built in VS2008), but I've tried a number of "alternate" versions of the code in my attempts to get this working. Here's the code that I'm currently using:
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.Shared
Module modReports
Private WithEvents DocumentToPrint As New Printing.PrintDocument
Private Sub ShowReport(ByVal LID As Integer, ByVal InHouse As Boolean)
Dim Report As New ReportDocument
Dim ReportParameters As ParameterFieldDefinitions = Nothing
Dim Parameter As ParameterFieldDefinition = Nothing
Dim ApplicationValue As ParameterDiscreteValue = Nothing
Dim ReportValues As ParameterValues = Nothing
Dim ReportViewer As New frmReport
Dim Response As DialogResult = DialogResult.Cancel
PrintingReport = True
Report.Load(CRYSTAL_REPORT_FILE_PATH & "ExampleReport.rpt")
Report.Refresh()
Report.VerifyDatabase()
ReportParameters = Report.DataDefinition.ParameterFields
Parameter = ReportParameters.Item("PrintAll")
ReportValues = New ParameterValues
ApplicationValue = New ParameterDiscreteValue
'Parameter.CurrentValues.Clear()
'ReportValues.Clear()
ReportValues = Parameter.CurrentValues
If LID = 7777 Then
ApplicationValue.Value = True
Else
ApplicationValue.Value = False
End If
ReportValues.Add(ApplicationValue)
Parameter.ApplyCurrentValues(ReportValues)
Response = MessageBox.Show("Do you want to send this report directly to the printer?", "SEND TO PRINTER", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
If Response = DialogResult.No Then
With ReportViewer
.rptViewer.ReportSource = Nothing
.rptViewer.ReportSource = Report
.WindowState = FormWindowState.Maximized
.rptViewer.RefreshReport()
' Set zoom level: 1 = Page Width, 2 = Whole Page, 25-100 = zoom %
.rptViewer.Zoom(1)
.rptViewer.Show()
.ShowDialog()
End With
ElseIf Response = DialogResult.Yes Then
Dim SelectPrinter As New PrintDialog
Dim PrinterSelected As DialogResult = DialogResult.Cancel
With SelectPrinter
.Document = DocumentToPrint
.AllowPrintToFile = False
.AllowSelection = False
.AllowCurrentPage = False
.AllowSomePages = False
.PrintToFile = False
End With
PrinterSelected = SelectPrinter.ShowDialog
If PrinterSelected = DialogResult.OK Then
Dim Copies As Integer = DocumentToPrint.PrinterSettings.Copies
Dim PrinterName As String = DocumentToPrint.PrinterSettings.PrinterName
Dim LastPageNumber As Integer = 1
Dim PrintBuffer As String = String.Empty
LastPageNumber = Report.FormatEngine.GetLastPageNumber(New ReportPageRequestContext)
Report.PrintOptions.PrinterName = PrinterName
Report.PrintOptions.PrinterDuplex = DocumentToPrint.PrinterSettings.Duplex
Report.PrintToPrinter(Copies, True, 1, LastPageNumber)
If Copies = 1 Then
PrintBuffer = "Printed " & Copies & " copy of "
Else
PrintBuffer = "Printed " & Copies & " copies of "
End If
If LastPageNumber = 1 Then
PrintBuffer += LastPageNumber.ToString & " page."
Else
PrintBuffer += LastPageNumber.ToString & " pages."
End If
MessageBox.Show("The report was sent to the following printer:" & vbCrLf & " • " & PrinterName & vbCrLf & PrintBuffer, "REPORT PRINTED", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
PrintingReport = False
End Sub
End Module
The report itself is built to use an XML file as the data source, which is dynamically created by this application. All of that works normally, and oddly enough, if I send the report directly to the printer, it seems to print correctly without prompting me. It's only a problem when I try to display the report through the CrystalReportViewer object.
Some of the things I've tried without success:
I've tried with and without calling the Clear() methods on the
Parameter.CurrentValues and ReportValues objects.
I've tried moving all of the parameter setting logic to after I set the
ReportSource of the CrystalReportViewer control (rptViewer.ReportSource)
I've tried using alternate Crystal Reports objects (ParameterFields instead of ParameterFieldDefinitions and ParameterField instead of ParameterFieldDefinition).
I've tried removing all of the "complicated" code and just using the SetParameterValue method (i.e., Report.SetParameterValue("PrintAll", True)
I've even tried creating different types of parameter fields in the report itself (String, Boolean, Number) and passing appropriate values for those datatypes.
If I walk through the code, it doesn't appear to error out anywhere, and everything looks like it's working just great until I get to the .rptViewer.RefreshReport() line in the With ReportViewer block. I've verified that all of the parameters and values have only the value I am "selecting" via the application by checking them every step up to that point, and it all looks exactly as I expect it to look.
But the application (via Crystal Reports) continues to prompt me for the value I just passed in the code. If I select the value in that prompt, the report does generate correctly based on the value I select, but no matter what I "pass" in the programming, the prompt always defaults to True.
Does anyone have any suggestions that I may have overlooked for how to get this parameter to correctly pass to the CrystalReportViewer control? Please let me know if you need any additional information or have any questions about what I've set up so far here. Thank you in advance.
Okay, so based on the information I found over on http://www.it-sideways.com/2011/10/how-to-disable-parameter-prompt-for.html, it seems that the RefreshReport method for the CrystalReportViewer control basically wipes out any parameters and/or log on information:
1. ) Do not invoke CrystalReportViewer.RefreshReport Method
This method will refresh the data for the report currently displayed
in the CrystalReportViewer control. The report will prompt for
parameters or logon info is necessary.
So, this method is not needed unless the same
CrystalDecisions.CrystalReports.Engine.ReportDocument object is
reused.
By commenting out that line of the code, I was able to prevent the parameter prompt from being displayed. The only issue I have after making that change is that, even though the zoom level is being set to 1 (page width), and when I run the project the CrystalReportViewer control even shows that it's correctly set in the status bar ('Zoom Factor: Page Width' is displayed), the report itself is not actually zoomed in to the page width.
With the RefreshReport method uncommented, if I manually provided the value for my parameter, it would display the report properly zoomed. If I add the zoom button to the control (.rptViewer.ShowZoomButton = True), I can manually choose the Page Width option, which then correctly "re-zooms" the report to the desired level, but it won't immediately display that way if the RefreshReport method is not called.
Regardless, I can spend some time trying to fight that now, but I finally have it properly setting, passing and displaying the results of my parameter. I hope this helps someone else running into this issue.

Restrict Image by selecting it's URL

I am trying to add Images from websites and I am facing poblem with an issue which is that when I am trying to go to google images and trying to add some Images and when I right click for some images I find "Copy Image URL" and for some I don't find it and I find "Copy link address".Now I want my users to restrict from adding the Images which contain "Copy Image URL"
And I am attaching Images so that you'll understand me in a better way.
How do I do that?
Here is the code for saving the image:
Dim dir_name As String = txtDirectory.Text
If Not dir_name.EndsWith("\") Then dir_name &= "\"
For Each pic As PictureBox In flpPictures.Controls
Dim bm As Bitmap = CType(pic.Image, Bitmap)
Dim filename As String = CStr(pic.Tag)
filename = filename.Substring(filename.LastIndexOf("/") + 1)
Dim ext As String = filename.Substring(filename.LastIndexOf("."))
'Here it gives me an error at(filename.lastindexof(".")
Dim full_name As String = dir_name & filename
Select Case ext
Case ".bmp"
bm.Save(full_name, Imaging.ImageFormat.Bmp)
Case ".gif"
bm.Save(full_name, Imaging.ImageFormat.Gif)
Case ".jpg", "jpeg"
bm.Save(full_name, Imaging.ImageFormat.Jpeg)
Case ".png"
bm.Save(full_name, Imaging.ImageFormat.Png)
Case ".tiff"
bm.Save(full_name, Imaging.ImageFormat.Tiff)
Case Else
MessageBox.Show( _
"Unknown file type " & ext & _
" in file " & filename, _
"Unknown File Type", _
MessageBoxButtons.OK, _
MessageBoxIcon.Error)
End Select
Next pic
Beep()
'WEB CLIENT IS NEEDED TO DO THE DOWNLOAD
Dim MyWebClient As New System.Net.WebClient
'BYTE ARRAY HOLDS THE DATA
Dim ImageInBytes() As Byte = MyWebClient.DownloadData(url)
'CREATE A MEMORY STREAM USING THE BYTES
Dim ImageStream As New IO.MemoryStream(ImageInBytes)
'CREATE A BITMAP FROM THE MEMORY STREAM
PictureBox1.Image = New System.Drawing.Bitmap(ImageStream)
In the top screenshot, you are right-clicking directly on an image.
In the bottom screenshot, you are right-clicking on an empty div with a z-index that puts it above the image.
Here's an example:
<a href="http://example.com">
<img src="myImg.jpg" style="position: absolute;" />
<div style="z-index:1; position:absolute; width:100%; height:100%;"></div>
</a>
When you mouse over the link in Google Images another div is shown on top that contains the saveable image. Have a look with Firebug and see for yourself :)
Note that there is no perfect way to prevent users from saving images from your website. You can disable right click, mask the image with a div, mask the image with a transparent image (so the user can right-click and save the image but they get the wrong one), prevent caching etc but ultimately any tech savvy user can get around this. Still, these approaches will stop casual users so it's better than nothing. If you want to find out more about the methods that I just named, I suggest Googling for "disable save image as" or "disable copy image url".
maybe helpful
Sub Base64Convert(ByVal Base64MSG As String)
'Setup image and get data stream together
Dim img As System.Drawing.Image
Dim MS As System.IO.MemoryStream = New System.IO.MemoryStream
Dim b64 As String = Base64MSG
Dim b() As Byte
'Converts the base64 encoded msg to image data
b = Convert.FromBase64String(b64)
MS = New System.IO.MemoryStream(b)
'creates image
img = System.Drawing.Image.FromStream(MS)
'writes image for displaying
img.Save(Request.ServerVariables("APPL_PHYSICAL_PATH") & "LabelInfo.tiff", System.Drawing.Imaging.ImageFormat.Tiff)
'cleaning up house
img.Dispose()
MS.Close()
End Sub