I have a column that stored picture in an MS Access database. In that column I right-click it and insert object which is picture from file
and it said "package" in the column.
The idea is to upload picture to 'pic' column in access database from file, and using 'querypic' table adapter query with parameter is 'comboname.text' is selected to return picture and store it as binary in byte of array
but when i convert it to image i got an error
System.ArgumentException: 'Parameter is not valid.
I checked my b() which is array of byte and it got result {length=40276}
can someone help me?
Private Sub cmdSelect_Click(sender As Object, e As EventArgs) Handles cmdSelect.Click
Dim facultytabeladapt As New CSE_DEPTDataSetTableAdapters.FacultyTableAdapter
Dim b() As Byte
Dim s As String
b = facultytabeladapt.querypic(ComboName.Text)
PhotoBox.Image = b21(b)
End Sub
Private Function b21(ByVal b() As Byte) As Image
Dim imgc As New ImageConverter
Dim imgpic As Image = CType(imgc.ConvertFrom(b), Image) 'it has error "System.ArgumentException: 'Parameter is not valid."
Return imgpic
End Function
this probably because of the OLEDB object in pic that i upload directly to access and not RAW binary file
Edit:
querypic is
SELECT pic
FROM Faculty
WHERE (faculty_name = ?)
where faculty_name is comboname.text
If you already have a byte array, create a memory stream from the byte array, then create an image from the stream. Don't forget to add Import System.IO to use MemoryStream class.
Private Function b21(ByVal b() As Byte) As Image
Dim ms As New MemoryStream(b) ' create memory stream from byte array
Return Image.FromStream(ms) ' create image from memory stream
End Function
Full code:
Imports System.IO
Imports System.Drawing.Imaging
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim b() As Byte
b = ReadImage(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) & "\test.png")
PhotoBox.Image = b21(b)
End Sub
Private Function b21(ByVal b() As Byte) As Image
Dim ms As New MemoryStream(b) ' create memory stream from byte array
Return Image.FromStream(ms) ' create image from memory stream
End Function
''' <summary>
''' This function reads a file and returns a byte array
''' </summary>
''' <param name="file">A file in full path name</param>
''' <returns>A byte array of the image</returns>
Private Function ReadImage(file As String) As Byte()
Dim image As Image = Image.FromFile(file) ' read image from file
Dim ms As New MemoryStream ' prepare a memory stream
image.Save(ms, ImageFormat.Png) ' save the image into memory stream
Return ms.ToArray() ' return byte array
End Function
End Class
Related
I use ESC/P or Epson Standard Code for Printers which aims to make bold. But I found there was an error "the given path's format is not supported". Is there a best solution?
Thanks
the given path's format is not supported
Dim ESC As String = "\u001B"
Dim BoldOn As String = (ESC + ("E" + "\u0001"))
Dim BoldOff As String = (ESC + ("E" + "\0"))
Public Shared Function SendFileToPrinter(ByVal szPrinterName As String, ByVal szFileName As String) As Boolean
' Open the file.
Using fs As New FileStream(szFileName, FileMode.Open)
' Create a BinaryReader on the file.
Dim br As New BinaryReader(fs)
' Dim an array of bytes big enough to hold the file's contents.
Dim bytes(fs.Length - 1) As Byte
Dim bSuccess As Boolean = False
' Your unmanaged pointer.
Dim pUnmanagedBytes As New IntPtr(0)
Dim nLength As Integer
nLength = Convert.ToInt32(fs.Length)
' Read the contents of the file into the array.
bytes = br.ReadBytes(nLength)
' Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength)
' Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength)
' Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength)
' Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes)
Return bSuccess
End Using
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim printer As String = "Generic / Text Only"
For i As Integer = 1 To 1
SendFileToPrinter(printer, (BoldOn + ("C:\vDos\#LPT1.asc" + BoldOff)))
'SendFileToPrinter(printer, "C:\vDos\#LPT1.asc") if I use this code then the error does not appear
Next i
End Sub
Your are passing the result of (BoldOn + ("C:\vDos\#LPT1.asc" + BoldOff)) to the szFileName parameter of your method but the one and only place that parameter is being used is here:
Using fs As New FileStream(szFileName, FileMode.Open)
The prefix and suffix you're adding are creating a value that is not a valid file path as far as the FileStream constructor is concerned, hence the exception. You need to pass a valid file path to that constructor.
It appears that that prefix and suffix are supposed to be passed to the printer somehow, but you're not doing that. My guess would be that you need to add that prefix and suffix to the actual data from the file, not the file path, e.g.
Dim BoldOn As Byte() = Encoding.UTF8.GetBytes(ESC + ("E" + "\u0001"))
Dim BoldOff As Byte() = Encoding.UTF8.GetBytes(ESC + ("E" + "\0"))
Dim fileContents = File.ReadAllBytes(filePath)
Dim dataToPrint = BoldOn.Concat(fileContents).Concat(BoldOff).ToArray()
It appears that I need spell it out in detail, so here's your original code modified to incorporate what I explained above:
Private Shared ESC As String = "\u001B"
Private Shared BoldOn As Byte() = Encoding.UTF8.GetBytes(ESC + ("E" + "\u0001"))
Private Shared BoldOff As Byte() = Encoding.UTF8.GetBytes(ESC + ("E" + "\0"))
Public Shared Function SendFileToPrinter(printerName As String, filePath As String) As Boolean
Dim bytes = BoldOn.Concat(File.ReadAllBytes(filePath)).Concat(BoldOff).ToArray()
Dim byteCount = bytes.Length
Dim unmanagedBytesPointer = Marshal.AllocCoTaskMem(byteCount)
Marshal.Copy(bytes, 0, unmanagedBytesPointer, byteCount)
Dim success = SendBytesToPrinter(printerName, unmanagedBytesPointer, byteCount)
Marshal.FreeCoTaskMem(unmanagedBytesPointer)
Return success
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim printer = "Generic / Text Only"
SendFileToPrinter(printer, "C:\vDos\#LPT1.asc")
End Sub
Note that it is just an educated guess that you need to combine those printer commands with the file contents. It's up to you to confirm that and, if it's not the case, find out what is required.
I would like to convert byte to string and back, I've tried this:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim bytes() As Byte = My.Computer.FileSystem.ReadAllBytes("C:\Archive.zip")
Dim filestream As System.IO.FileStream = System.IO.File.Create("C:\Archive2.zip")
Dim info As Byte() = fromstringtobyte(frombytetostring(bytes))
filestream.Write(info, 0, info.Length)
filestream.Close()
End Sub
Private Function frombytetostring(ByVal b() As Byte)
Dim s As String
s = Convert.ToBase64String(b)
Return s
End Function
Private Function fromstringtobyte(ByVal s As String)
Dim b() As Byte
b = System.Text.Encoding.UTF8.GetBytes(s)
Return b
End Function
End Class
The new file that was created was corrupted.
Can you please recommend any other solutions?
Sorry for my bad English, it ain't my main language.
Your byte to string conversion is wrong. You need to use:
System.Text.Encoding.[your encoding].GetString(bytes)
Source:
How to: Convert an Array of Bytes into a String in Visual Basic
How to: Convert Strings into an Array of Bytes in Visual Basic
You might want to read this as well to decide which encoding to use: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
I've found an answer, the new code is:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim bytes() As Byte = My.Computer.FileSystem.ReadAllBytes("C:\Program Files (x86)\Windows Repair Pro\Windows Repair Pro (All In One) 3.8.7\Tweaking.com - Windows Repair Portable\Archive.zip")
Dim filestream As System.IO.FileStream = System.IO.File.Create("C:\Program Files (x86)\Windows Repair Pro\Windows Repair Pro (All In One) 3.8.7\Tweaking.com - Windows Repair Portable\Archive2.zip")
Dim info As Byte() = fromstringtobyte(frombytetostring(bytes))
filestream.Write(info, 0, info.Length)
filestream.Close()
End Sub
Private Function frombytetostring(ByVal b() As Byte)
Dim s As String
s = BitConverter.ToString(b)
Return s.Replace("-", "")
End Function
Private Function fromstringtobyte(ByVal s As String)
Dim B() As Byte = New Byte(s.Length / 2 - 1) {}
For i As Integer = 0 To s.Length - 1 Step 2
B(i / 2) = Convert.ToByte(s.Substring(i, 2), 16)
Next
Return B
End Function
End Class
I'm using this code to read my XFA data to my vb.net application. However, I cannot figure out how to load the populatedPDFFrom to the application.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim filePath As String
filePath = "d:\waiver_testing\test_pdf\rfrprg67.pdf"
TextBox1.Text = Export(filePath)
End Sub
Public Shared Function Export(populatedPDFForm As System.IO.Stream) As System.IO.MemoryStream
' Exports XFA data from a PDF File
' <param name="populatedPDFForm">a readable stream of the PDF with a populated form</param>
' <returns>A stream containing the exported XML form data</returns>
Dim outputStream As New System.IO.MemoryStream()
Dim reader As New iTextSharp.text.pdf.PdfReader(populatedPDFForm)
Dim settings As XmlWriterSettings = New XmlWriterSettings
settings.Indent = True
'settings.OmitXmlDeclaration = True
Using writer = XmlWriter.Create(outputStream, settings)
reader.AcroFields.Xfa.DatasetsNode.WriteTo(writer)
End Using
Return outputStream
End Function
Error on line:
textbox1.text = Export(filePath)
Error:
Value type "String" cannot be converted to to "System.IO.Stream"
Can someone please throw me a bone?
Well, you can not assign a MemoryStream to a string. You need to convert it first. For example to read the stream as Ascii you can use Encoding.ASCII.GetString.
Also, your Export function seems to take in a stream as a parameter and not a file path. To handle that write:
Using inStream As Stream = File.OpenRead(filePath)
TextBox1.Text = Encoding.ASCII.GetString(Export(inStream).ToArray())
End Using
I am trying to generate byte array from a stream of ".rtf" file.
The code is as follows:
Public Sub Button_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Try
Dim result As System.Nullable(Of Boolean) = textDialog.ShowDialog()
If result = True Then
Dim fileStream As Stream = textDialog.OpenFile()
GetStreamAsByteArray(fileStream)
End If
Catch ex As Exception
End Try
End Sub
Private Function GetStreamAsByteArray(ByVal stream As System.IO.Stream) As Byte()
Dim streamLength As Integer = Convert.ToInt32(stream.Length)
Dim fileData As Byte() = New Byte(streamLength) {}
' Read the file into a byte array
stream.Read(fileData, 0, streamLength)
stream.Flush()
stream.Close()
Return fileData
End Function
The above code generates stream length for the file opened however the byte array returned only have 0's in the array.
How can i generate correct byte array?
You function does not returns the byte array to any object. This example works for me:
Dim bytes = GetStreamAsByteArray(textDialog.File.OpenRead)
MessageBox.Show(bytes.Length.ToString)
Other threads have covered that file.encrypt on vb is not supported on W7HE. however i cant find a simple work around for it, and the only other function i know for encryption is using:
Imports system.security.Cryptography
and then doing along the lines of
Dim rsa As New RSACryptoServiceProvider
Dim encoder As New UTF8Encoding
etc,etc
however that only does strings, i need to encrypt the file as a whole.
Any ideas would be greatly appreciated
file.encrypt uses EFS, which is actually transparent encryption; the user account stores the master certificate, so anyone logged in under that account can access the file contents in any application. Depending on what you need, that might not be what you want at all. If you want to replicate EFS behavior for your app alone, it's as simple as storing a master password somewhere in the user's private files, split your data file into 'key' and 'data' sections, and encrypt the key with the master password. (Real EFS has some subtleties: It can encrypt the password separately for many different users, so it allows different users access per-file, giving a recovery option in case the main user's password is lost. It also uses the user's password to encrypt the master password, so if anyone changes the password they won't be able to open files.)
The basic method is just prompt the user for the password and use that to encrypt or decrypt the entire file at once rather than a string at a time. Serialize your file however you would unencrypted, then pass that whole byte array to something similar to EncryptStringToBytes_Aes. The one and only difference if you're writing bytes instead of a string is changing:
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
to
csEncrypt.Write(plainText);
Either way, for the actual crypto you'd use AesCryptoServiceProvider, not RSACryptoServiceProvider, which is for the top-level authentication and encryption of keys/passwords that get passed to AES and similar algorithms. It's rarely used to encrypt whole files, and is dreadfully slow when you do.
I'm enclosing a program I wrote to help you along the way. It is very effective and will encrypt whatever you want. I left notes in it to answer all your questions. At the bottom, you will see an added class to reduce memory usage of the program. It works rather well, (by 8% -10%) Enjoy. Items needed: *3 buttons (Browse) (Encrypt) (Decrypt) *1 TextBox For the project video, see my link:
Part 1: https://www.youtube.com/watch?v=sVaA2q8ttzQ
Part 2: https://www.youtube.com/watch?v=TyafeBJ53YU
'Created by: Rythorian77 | github.com/rythorian77
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim ramClass As New AESRam()
End Sub
Private Sub Browse_Click(sender As Object, e As EventArgs) Handles Browse.Click
'Allows you to access files from folders
Dim fetchCryptDialog As New OpenFileDialog With {
.CheckFileExists = True,
.InitialDirectory = "C:\",
.Multiselect = False
}
If fetchCryptDialog.ShowDialog = DialogResult.OK Then
TextBox1.Text = fetchCryptDialog.FileName
End If
End Sub
Private Sub Encrypt_Click(sender As Object, e As EventArgs) Handles Encrypt.Click
'File path goes to textbox
Dim Rythorian77 As String = TextBox1.Text
'This password can be whater you want.
Dim password As String = "123456789ABCDEFG!##$%^&*()_+"
'A data type is the characteristic of a variable that determines what kind of data it can hold.
'Data types include those in the following table as well as user-defined types and specific types of objects.
Dim key As Byte() = New Byte(31) {}
'When overridden in a derived class, encodes a set of characters into a sequence of bytes.
Encoding.Default.GetBytes(password).CopyTo(key, 0)
'RijndaelManaged still works but is considered obsolete in todays world so we use AES
'Represents the abstract base class from which all implementations of the Advanced Encryption Standard (AES) must inherit.
'https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.aes?view=net-6.0
Dim aes As New RijndaelManaged() With
{
.Mode = CipherMode.CBC,
.KeySize = 256,
.BlockSize = 256,
.Padding = PaddingMode.Zeros
}
'Reads a sequence of bytes from the current memory stream and advances the position within the memory stream by the number of bytes read.
Using mnemonicData As New MemoryStream
'Defines a stream that links data streams to cryptographic transformations.
Using cStream As New CryptoStream(mnemonicData, aes.CreateEncryptor(key, key), CryptoStreamMode.Write)
Dim buffer As Byte() = File.ReadAllBytes(Rythorian77)
cStream.Write(buffer, 0, buffer.Length)
Dim appendBuffer As Byte() = mnemonicData.ToArray()
Dim finalBuffer As Byte() = New Byte(appendBuffer.Length - 1) {}
appendBuffer.CopyTo(finalBuffer, 0)
File.WriteAllBytes(Rythorian77, finalBuffer)
End Using
End Using
End Sub
'The above code notes compliment the same
Private Sub Decrypt_Click(sender As Object, e As EventArgs) Handles Decrypt.Click
Dim Rythorian77 As String = TextBox1.Text
Dim password As String = "123456789ABCDEFG!##$%^&*()_+"
Dim key As Byte() = New Byte(31) {}
Encoding.Default.GetBytes(password).CopyTo(key, 0)
Dim aes As New RijndaelManaged() With
{
.Mode = CipherMode.CBC,
.KeySize = 256,
.BlockSize = 256,
.Padding = PaddingMode.Zeros
}
Using mnemonicData As New MemoryStream
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> < aes.CreateDecryptor > is the only change from above aes.CreateEncryptor
Using cStream As New CryptoStream(mnemonicData, aes.CreateDecryptor(key, key), CryptoStreamMode.Write)
Dim buffer As Byte() = File.ReadAllBytes(Rythorian77)
cStream.Write(buffer, 0, buffer.Length)
Dim appendBuffer As Byte() = mnemonicData.ToArray()
Dim finalBuffer As Byte() = New Byte(appendBuffer.Length - 1) {}
appendBuffer.CopyTo(finalBuffer, 0)
File.WriteAllBytes(Rythorian77, finalBuffer)
End Using
End Using
End Sub
End Class
**Add this separate Class:**
Imports System.Runtime.InteropServices
Public Class AESRam
'This controls the amount of RAM that your process uses, it doesn't otherwise have any affect on the virtual memory size of your process.
'Sets the minimum and maximum working set sizes for the specified process.
'This will cut memory usage in half.
<DllImport("KERNEL32.DLL", EntryPoint:="SetProcessWorkingSetSize", SetLastError:=True, CallingConvention:=CallingConvention.StdCall)>
Friend Shared Function SetProcessWorkingSetSize(pProcess As IntPtr, dwMinimumWorkingSetSize As Integer, dwMaximumWorkingSetSize As Integer) As Boolean
End Function
'Retrieves a pseudo handle for the current process.
<DllImport("KERNEL32.DLL", EntryPoint:="GetCurrentProcess", SetLastError:=True, CallingConvention:=CallingConvention.StdCall)>
Friend Shared Function GetCurrentProcess() As IntPtr
End Function
'See Above
Public Sub New()
Dim pHandle As IntPtr = GetCurrentProcess()
SetProcessWorkingSetSize(pHandle, -1, -1)
End Sub
End Class