I can create an image on the server from a byte array stored in the database. But how do I combine each byte array into one image. Basically I want to stack them on top of each other (they are all 1366px width and 618px height) and then save that to a png image. I will then get that image from the server and return to the web page (which I can do now for one image). Hope you can help.
This code in asp.net web forms creates an image which i return the filename as a return in a webmethod function back to the browser.
Public Shared Function Base64ToImage(ByVal base64String As String, ByVal id As String) As String
'http://www.dailycoding.com/Posts/convert_image_to_base64_string_and_base64_string_to_image.aspx
' Convert Base64 String to byte[]
Dim sFileName As String = String.Empty
Try
Dim imageBytes As Byte() = Convert.FromBase64String(base64String)
Dim ms As New MemoryStream(imageBytes, 0, imageBytes.Length)
' Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length)
Dim image__1 As Image = Image.FromStream(ms, True)
sFileName = "img_" & id & ".png"
Dim sPath As String = HttpContext.Current.Server.MapPath("images\")
image__1.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)
Catch ex As Exception
End Try
'
Return sFileName
End Function
I have tried this, looping through the records and then trying to combine them with sourcecopy but I can't get it to combine them?
Public Shared Function Base64ToImage2(ByVal dt As DataTable) As String
' Convert Base64 String to byte[]
Dim sFileName As String = String.Empty
Dim base64String As String, id As String
'if first record create image
'on 2nd or greater in dt then combine images
Try
Dim iCount As Integer = 0
Dim image__1 As Image = Nothing
Dim compositeImage As Image = Nothing
Dim sPath As String = String.Empty
If dt.Rows.Count > 0 Then
For Each myRow As DataRow In dt.Rows
'getImage = getImage() & Base64ToImage(myRow("image_data").ToString(), myRow("id").ToString()) & "|"
If iCount = 0 Then
Dim imageBytes As Byte() = Convert.FromBase64String(myRow("image_data").ToString())
Dim ms As New MemoryStream(imageBytes, 0, imageBytes.Length)
' Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length)
image__1 = System.Drawing.Image.FromStream(ms)
'sFileName = "img_1.png"
'sPath = HttpContext.Current.Server.MapPath("images\")
'image__1.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)
'compositeImage = New Bitmap(image__1.Width, image__1.Height)
Else
Dim imageBytes As Byte() = Convert.FromBase64String(myRow("image_data").ToString())
Dim ms2 As New MemoryStream(imageBytes, 0, imageBytes.Length)
' Convert byte[] to Image
ms2.Write(imageBytes, 0, imageBytes.Length)
Dim image__2 As Image = System.Drawing.Image.FromStream(ms2)
Dim g As Graphics = Graphics.FromImage(image__1)
g.CompositingMode = CompositingMode.SourceCopy
g.DrawImage(image__2, 0, image__1.Height)
sFileName = "img_1.png"
'sPath = HttpContext.Current.Server.MapPath("images\")
'image__2.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)
End If
iCount = iCount + 1
Next myRow
End If
'sFileName = "img_1.png"
'Dim sPath As String = HttpContext.Current.Server.MapPath("images\")
'compositeImage.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)
Catch ex As Exception
End Try
'
Return sFileName
End Function
Solved! After a ton of searching and reading I was able to combine png images into one! Each image is created from a memory stream and then appended to a bitmap with NewRectangle which is the key. Once I loop through the records from the database, I have one image which is downloaded to the client in a webmethod return. The width and height are pulled from the client to the webmethod and passed into the function so the image is scaled to fit the browser inner dimensions (to avoid any scrollbars).
JS on the client for the dimensions:
mywidth = window.innerWidth
myheight = window.innerHeight
The code to convert the base64 byte image is as follows...
Public Shared Function Base64ToImage2(ByVal dt As DataTable, ByVal Image_Width As String, ByVal Image_Height As String) As String
Dim sFileName As String = String.Empty
Dim sPath As String = HttpContext.Current.Server.MapPath("images\")
Dim myimage As Image = Nothing
' Create a new bitmap object 400 pixels wide by 60 pixels high
Dim objBitmap As New Bitmap(CInt(Image_Width), CInt(Image_Height))
'' Create a graphics object from the bitmap
Dim objGraphic As Graphics = Graphics.FromImage(objBitmap)
'if first record create image
'on 2nd or greater in dt then combine images
Try
If dt.Rows.Count > 0 Then
For Each myRow As DataRow In dt.Rows
Dim imageBytes As Byte() = Convert.FromBase64String(myRow("image_data").ToString())
Dim ms As New MemoryStream(imageBytes, 0, imageBytes.Length)
' Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length)
myimage = System.Drawing.Image.FromStream(ms)
objGraphic.DrawImage(myimage, New Rectangle(0, 0, CInt(Image_Width), CInt(Image_Height)))
Next myRow
sFileName = "img_1.png"
objBitmap.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)
End If
Catch ex As Exception
End Try
'
Return sFileName
End Function
In case someone else is looking for something similar in C# where you're trying to load an image source with the result, here's the code:
private void LoadImage()
{
string src = string.empty;
byte[] mergedImageData = new byte[0];
mergedImageData = MergeTwoImageByteArrays(watermarkByteArray, backgroundImageByteArray);
src = "data:image/png;base64," + Convert.ToBase64String(mergedImageData);
MyImage.ImageUrl = src;
}
private byte[] MergeTwoImageByteArrays(byte[] imageBytes, byte[] imageBaseBytes)
{
byte[] mergedImageData = new byte[0];
using (var msBase = new MemoryStream(imageBaseBytes))
{
System.Drawing.Image imgBase = System.Drawing.Image.FromStream(msBase);
Graphics gBase = Graphics.FromImage(imgBase);
using (var msInfo = new MemoryStream(imageBytes))
{
System.Drawing.Image imgInfo = System.Drawing.Image.FromStream(msInfo);
Graphics gInfo = Graphics.FromImage(imgInfo);
gBase.DrawImage(imgInfo, new Point(0, 0));
//imgBase.Save(Server.MapPath("_____testImg.png"), ImageFormat.Png);
MemoryStream mergedImageStream = new MemoryStream();
imgBase.Save(mergedImageStream, ImageFormat.Png);
mergedImageData = mergedImageStream.ToArray();
mergedImageStream.Close();
}
}
return mergedImageData;
}
Related
Could someone help me fix this code?
This is actually fully working but, this code will automatically merged the output files
I want to decrypt each file only and not automatically merged
Here's the code:
Sub decrypt()
Try
Cursor = Cursors.WaitCursor
Application.DoEvents()
If txtFileName.Text = "" Then
txtFileName.Text = "DecryptedFile"
Else
End If
Dim folder As String = txtSource.Text
Dim encryptionKey As Byte() = File.ReadAllBytes(txtKey.Text)
Dim outputFile As String = (txtFilePath.Text + "\" + txtFileName.Text + ".ts")
Using outputFileStream As FileStream = New FileStream(outputFile, FileMode.Create)
Dim files = Directory.GetFiles(folder, "*.ts")
For i As Integer = 0 To files.Length - 1
Dim encryptionIV As Byte() = New Byte(15) {}
Using inputFileStream As FileStream = New FileStream(files(i), FileMode.Open)
Using aes = New AesManaged With {
.Key = encryptionKey,
.IV = encryptionIV,
.Mode = CipherMode.CBC
}
Using encryptor = aes.CreateDecryptor()
Using cryptoStream = New CryptoStream(inputFileStream, encryptor, CryptoStreamMode.Read)
cryptoStream.CopyTo(outputFileStream)
End Using
End Using
End Using
End Using
Next
End Using
Cursor = Cursors.Default
Catch ex As Exception
Cursor = Cursors.Default
End Try
End Sub
i've found this function for VB.net and i used in an .aspx page and works.
Private Sub LoadImageFromURL(URL As String, ByRef Img As Drawing.Bitmap)
Const BYTESTOREAD As Integer = 10000
Dim myRequest As WebRequest = WebRequest.Create(URL)
Dim myResponse As WebResponse = myRequest.GetResponse()
Dim ReceiveStream As Stream = myResponse.GetResponseStream()
Dim br As New BinaryReader(ReceiveStream)
Dim memstream As New MemoryStream()
Dim bytebuffer As Byte() = New Byte(BYTESTOREAD - 1) {}
Dim BytesRead As Integer = br.Read(bytebuffer, 0, BYTESTOREAD)
While BytesRead > 0
memstream.Write(bytebuffer, 0, BytesRead)
BytesRead = br.Read(bytebuffer, 0, BYTESTOREAD)
End While
Img = New Drawing.Bitmap(memstream)
End Sub
I would like to limit the loading of a remote imagebased on:
1) Image size limit in Bytes
2) Max Dimension of the pic x,y
3) Accepted image types (jpg, png)
I'm not so expert on image manipulation so I ask for a little help to improve the function if is possible and to enable some sort of protection on the image URL tio avoid malicious use.
EDIT: I must use the function on a .aspx page
Thanks
I transformed into a function to validate the url and works.
Don't know if i can make it lighter and faster or if there is a better solution to do that.
Public Function ChkImageFromURL(URL As String) As Boolean
Dim myRequest As WebRequest = WebRequest.Create(URL)
myRequest.Method = WebRequestMethods.Http.Head
Dim myResponse As WebResponse = myRequest.GetResponse()
Dim ImageLen As Integer = myResponse.ContentLength
Dim ImageType As String = myResponse.ContentType
If ( Lcase(ImageType) <> "image/jpeg" AND Lcase(ImageType) <> "image/png" ) Or ImageLen > 300000 Then
return false
Else
return true
End if
End Function
I want to save an image which is resized using Imageresizer plugin to database.
Here is my code.
<HttpPost()>
<ValidateAntiForgeryToken()>
Async Function Edit(ByVal employeeMaster As EmployeeMaster, ByVal upload As HttpPostedFileBase) As Task(Of ActionResult)
Try
If ModelState.IsValid Then
If upload IsNot Nothing Then
'Dim imageData As Byte()= New [Byte](upload.InputStream.Length - 1) {} // this section saving to database which is original file ----- start
'upload.InputStream.Read(imageData, 0, CInt(upload.InputStream.Length))
'employeeMaster.Photo = imageData // --- end
Dim guid1 As String = Guid.NewGuid().ToString()
Dim filename = guid1
Dim versions = New Dictionary(Of String, String)()
Dim path1 = Server.MapPath("~/Content/")
versions.Add("", "maxwidth=600&maxheight=600&format=jpg")
For Each suffix As String In versions.Keys
upload.InputStream.Seek(0, SeekOrigin.Begin)
ImageBuilder.Current.Build(New ImageJob(upload.InputStream, path1 + filename, New Instructions(versions(suffix)), False, True))
Next
Dim savedFileName = Path.Combine(path1, Path.GetFileName(filename))
Return File(savedFileName, "application/octet-stream", filename)
upload.SaveAs(savedFileName)
Dim imageData As Byte()= New [Byte](upload.InputStream.Length - 1) {} // trying to save new image to database ----- start
upload.InputStream.Read(imageData, 0, CInt(upload.InputStream.Length))
employeeMaster.Photo = imageData // -----end
Dim size1 = upload.ContentLength
Dim fullPath As String = Request.MapPath("~/Content/" + filename)
If System.IO.File.Exists(fullPath) Then
Dim ex = "ok"
System.IO.File.Delete(fullPath)
End If
End If
db.Entry(employeeMaster).State = EntityState.Modified
Await db.SaveChangesAsync()
Dim json1 = New With {Key .message = "Updated Successfully", Key .error = "False"}
Return Json(json1, JsonRequestBehavior.AllowGet)
Else
'logic for when that description exists
'for example, to add to ModelState
ModelState.AddModelError("EmployeeCode", "EmployeeCode Exists")
End If
Catch ex As DbEntityValidationException
End Try
End Function
The uploaded file can be directly save to database. But I am compressing that image using Imageresizer plugin. Then it is saving to a folder.I am trying to read that saved image which is in the folder and save newly formed image to database. How can be it done?
I have solved the problem.
Here is the code
Dim _fileInfo As New System.IO.FileInfo(savedFileName)
Dim _NumBytes As Long = _fileInfo.Length
Dim _FStream As New System.IO.FileStream(savedFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read)
'upload.SaveAs(savedFileName)
imageData = New [Byte](_FStream.Length - 1) {}
_FStream.Read(imageData, 0, CInt(_FStream.Length))
employeeMaster.Photo = imageData
code snippet for my image upload:
'Read the file and convert it to Byte Array
Dim filePath As String = FileUpload1.PostedFile.FileName
Dim filename As String = Path.GetFileName(filePath)
Dim ext As String = Path.GetExtension(filename)
Dim contenttype As String = String.Empty
'Set the contenttype based on File Extension
Select Case ext
Case ".jpg"
contenttype = "image/jpg"
Exit Select
Case ".png"
contenttype = "image/png"
Exit Select
End Select
If Not contenttype Is String.Empty Then
Dim fs As Stream = FileUpload1.PostedFile.InputStream
Dim br As New BinaryReader(fs)
Dim bytes As Byte() = br.ReadBytes(fs.Length)
'insert the file into database
cmd.Parameters.Add("#imgName", SqlDbType.VarChar).Value = filename
cmd.Parameters.Add("#contentType", SqlDbType.VarChar).Value = contenttype
cmd.Parameters.Add("#data", SqlDbType.Binary).Value = bytes
Else
cmd.Parameters.Add("#imgName", SqlDbType.VarChar).Value = DBNull.Value
cmd.Parameters.Add("#contentType", SqlDbType.VarChar).Value = DBNull.Value
cmd.Parameters.Add("#data", SqlDbType.Binary).Value = DBNull.Value
End If
con.Open()
cmd.ExecuteNonQuery()
con.Close()
preview image:
Protected Sub preview_btn_Click(sender As Object, e As EventArgs) Handles preview_btn.Click
Session("ImageBytes") = FileUpload1.FileBytes
Image1.ImageUrl = "~/Handler1.ashx"
preview_btn.BackColor = Drawing.Color.Lime
preview_btn.ForeColor = Drawing.Color.White
Image1.BorderColor = Drawing.Color.Lime
End Sub
Handler1.ashx
<%# WebHandler Language="VB" Class="Handler1" %>
Imports System
Imports System.Web
Public Class Handler1 : Implements System.Web.IHttpHandler, System.Web.SessionState.IRequiresSessionState
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
If (context.Session("ImageBytes")) IsNot Nothing Then
Dim image As Byte() = DirectCast(context.Session("ImageBytes"), Byte())
context.Response.ContentType = "image/jpeg"
context.Response.BinaryWrite(image)
End If
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
The preview image works but whenever I invoke the preview image button, the FileUpload control get reset.
So from the FileUpload control's point of view, it is as if the user did not select any image in the first place.
I tried storing the value of FileUpload1.PostedFile.FileName in some variable first and then manually set back its value but FileUpload1.PostedFile.FileName appears to be read-only, which makes sense from a security perspective.
So workaround for this?
For a quick solution, I would do the following:
Preview - Save the posted file in session. Set the Image1 image url to handler.
Handler - Get the posted file from session. Write image to response.
Upload - Check if file exists in FileUpload1, get it. If not, get it
from session. Save image. Clear session.
Here's the code I would use:
EDIT : Changed the code to fix issue with larger (> 50kb) images
aspx.vb
Protected Sub btnUpload_Click(sender As Object, e As EventArgs) Handles btnUpload.Click
'Disabled DB operations for test
'Read the file and convert it to Byte Array
Dim filePath As String = String.Empty
Dim filename As String = String.Empty
Dim ext As String = String.Empty
Dim contenttype As String = String.Empty
Dim bytes As Byte()
If FileUpload1.HasFile Then
filePath = FileUpload1.PostedFile.FileName
Else
If (Session("MyFile") IsNot Nothing AndAlso Session("MyFileName") IsNot Nothing) Then
filePath = Session("MyFileName").ToString()
bytes = DirectCast(Session("MyFile"), Byte())
End If
End If
filename = Path.GetFileName(filePath)
ext = Path.GetExtension(filename)
'Set the contenttype based on File Extension
Select Case ext
Case ".jpg"
contenttype = "image/jpg"
Exit Select
Case ".png"
contenttype = "image/png"
Exit Select
End Select
If Not contenttype Is String.Empty Then
If FileUpload1.HasFile Then
Dim fs As Stream = FileUpload1.PostedFile.InputStream
Dim br As New BinaryReader(fs)
bytes = br.ReadBytes(fs.Length)
End If
'insert the file into database
cmd.Parameters.Add("#imgName", SqlDbType.VarChar).Value = filename
cmd.Parameters.Add("#contentType", SqlDbType.VarChar).Value = contenttype
cmd.Parameters.Add("#data", SqlDbType.Binary).Value = bytes
Else
cmd.Parameters.Add("#imgName", SqlDbType.VarChar).Value = DBNull.Value
cmd.Parameters.Add("#contentType", SqlDbType.VarChar).Value = DBNull.Value
cmd.Parameters.Add("#data", SqlDbType.Binary).Value = DBNull.Value
End If
con.Open()
cmd.ExecuteNonQuery()
con.Close()
'Cleanup
Session("MyFile") = Nothing
Session("MyFileName") = Nothing
End Sub
Protected Sub preview_btn_Click(sender As Object, e As EventArgs) Handles preview_btn.Click
If FileUpload1.PostedFile IsNot Nothing Then
Dim file As HttpPostedFile = FileUpload1.PostedFile
Dim data As Byte() = New [Byte](file.ContentLength - 1) {}
file.InputStream.Read(data, 0, file.ContentLength)
Session("MyFile") = data
Session("MyFileName") = FileUpload1.PostedFile.FileName
Image1.ImageUrl = "~/Handler1.ashx"
preview_btn.BackColor = Drawing.Color.Lime
preview_btn.ForeColor = Drawing.Color.White
Image1.BorderColor = Drawing.Color.Lime
End If
End Sub
Handler1.ashx
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
If (context.Session("MyFile")) IsNot Nothing Then
Dim storedImage = TryCast(context.Session("MyFile"), Byte())
If storedImage IsNot Nothing Then
context.Response.ContentType = "image/jpeg"
context.Response.BinaryWrite(storedImage)
End If
End If
End Sub
Hope it helps!
Protected Sub btnUpload_Click(ByVal sender As Object, e As EventArgs) Handles btnUpload.Click
Dim filePath As String = FileUpload.PostedFile.FileName
Dim filePath2 As String = FileUploadImage.PostedFile.FileName
Dim fileName As String = Path.GetFileName(filePath)
Dim ext As String = Path.GetExtension(fileName)
Dim contenttyppe As String = String.Empty
Select Case ext
Case ".pdf"
ContentType = "application/pdf"
Exit Select
Case ".jpg"
ContentType = "image/jpg"
Exit Select
Case ".pfx"
ContentType = "image/pfx"
Exit Select
Case ".png"
ContentType = "image/png"
Exit Select
Case ".gif"
ContentType = "image/gif"
Exit Select
Case ".doc"
ContentType = "application/vnd.ms-word"
Exit Select
Case ".docx"
ContentType = "application/vnd.ms-word"
Exit Select
Case ".xls"
ContentType = "application/vnd.ms-excel"
Exit Select
Case ".xlsx"
ContentType = "application/vnd.ms-excel"
Exit Select
Case ".pfx"
ContentType = "image/pfx"
Exit Select
End Select
If contenttyppe <> String.Empty Then
Dim fs As Stream = FileUpload.PostedFile.InputStream
Dim fi As Stream = FileUploadImage.PostedFile.InputStream
Dim br As New BinaryReader(fs)
Dim br2 As New BinaryReader(fi)
Dim bytes As Byte() = br.ReadBytes(fs.Length)
Dim bytes2 As Byte() = br2.ReadBytes(fi.Length)
Dim strQuery As String = "insert into APPUSERDTL (UID,APPCODE,APPEXPIRED,SIGNIMAGE, PFKFILE,HEADUID,PRINCIPALFROM,PRINCIPALTO,EXCEPTIONUSER,LastUpdate)" _
& "VALUES('',' ','',' #FileUpload ',' #FileUploadImage','','','','','')"
Dim cmd As New SqlCommand(strQuery)
cmd.Parameters.Add("#UID", Data.SqlDbType.Int).Value = bytes
cmd.Parameters.Add("#APPCODE", Data.SqlDbType.VarChar, 50).Value = bytes
cmd.Parameters.Add("#APPEXPIRED", Data.SqlDbType.DateTime).Value = bytes
cmd.Parameters.Add("#FileUpload", Data.SqlDbType.Image).Value = FileUpload
cmd.Parameters.Add("#FileUploadImage", Data.SqlDbType.VarBinary).Value = FileUploadImage
cmd.Parameters.Add("#HEADUID", Data.SqlDbType.Int).Value = bytes
cmd.Parameters.Add("#PRINCIPALFROM", Data.SqlDbType.Money).Value = bytes
cmd.Parameters.Add("#PRINCIPALTO", Data.SqlDbType.Money).Value = bytes
cmd.Parameters.Add("#EXCEPTIONUSER", Data.SqlDbType.Bit).Value = bytes
cmd.Parameters.Add("#LastUpdate", Data.SqlDbType.DateTime).Value = bytes
InsertUpdateData(cmd)
lblMsgUpload.ForeColor = System.Drawing.Color.Green
lblMesgImage.ForeColor = System.Drawing.Color.Green
lblMsgUpload.Text = "File Upload Successfully"
lblMesgImage.Text = "File Upload Successfuly"
Else
lblMesgImage.ForeColor = System.Drawing.Color.Red
lblMesgImage.Text = "File format not recognised." _
& " Upload Image/Word/PDF/Excel formats"
End If
' delete file upload
Dim fullPath = MapPath("~/upload/") + fileName
If System.IO.File.Exists(fullPath) Then
System.IO.File.Delete(fullPath)
End If
End Sub
==================================================
Public Function InsertUpdateData(ByVal cmd As SqlCommand) As Boolean
' Dim strConnString As New DBX
Dim strConnString As String = System.Configuration.ConfigurationManager.ConnectionStrings("connection").ConnectionString
Dim conn As New SqlConnection(strConnString)
cmd.CommandType = CommandType.Text
cmd.Connection = conn
Try
conn.Open()
cmd.ExecuteNonQuery()
Return True
Catch ex As Exception
Response.Write(ex.Message)
Return False
Finally
conn.Close()
conn.Dispose()
End Try
End Function
End Class
You have only two parameters placeholders in the query text (#FileUpload and #FileUploadImage). Then you define parameters for every field with various datatype, but then set them all with the same value (bytes). Finally the commas that should separe the values are placed wrongly in the query text. No wonder that you ExecuteNonQuery doesn't work
If you don't know the other values and your record could be inserted leaving that fields to their default value you could try with this trimmed down version of your query above. Otherwise you need to know the actual values to insert in the other fields and initialize the parameters value with the appropriate variables.
Dim strQuery As String = "insert into APPUSERDTL (SIGNIMAGE,PKFILE,LastUpdate) " & _
"VALUES(#FileUpload,#FileUploadImage, GetDate())"
Dim cmd As New SqlCommand(strQuery)
cmd.Parameters.Add("#FileUpload", Data.SqlDbType.Image).Value = FileUpload
cmd.Parameters.Add("#FileUploadImage", Data.SqlDbType.VarBinary).Value = FileUploadImage
InsertUpdateData(cmd)
As a last note, when you have errors it is always good to add the error message to your question. It is very helpfull to understand what happens in your code.