There are many suggestions for using the Image.FromStream(stream) on the Internet and look like they should do what I want. However, there is just one piece I don't fully understand.
I am making a GET request to a URL that returns a Byte Array which is an image. I make the request and get the response like this:
Public Function getPic(ByRef stu As String) As Image
Dim url As String = "myurl" & stu 'identifying number I am adding to the url
Dim hwrequest As HttpWebRequest = Net.WebRequest.Create(url)
hwrequest.Method = "Get"
Dim hwresponse = hwrequest.GetResponse().GetResponseStream()
Dim ms As New MemoryStream()
hwresponse.CopyTo(ms)
Dim img As Image
img = Image.FromStream(ms)
PictureBox1.Image = img
End Function
I have found two different code suggestions:
Public Function byteArrayToImage(ByVal byteArrayIn As Byte()) As Image
Using mStream As New MemoryStream(byteArrayIn)
Return Image.FromStream(mStream)
End Function
Here I understand I need to pass the Byte Array from my response to the function but that is where my understanding is lacking. When I pass in
Public Function byteArrayToImage(ByVal hwresponse As Byte()) As Image
Using mStream As New MemoryStream(hwresponse)
Return Image.FromStream(mStream)
I get "Value of Stream cannot be converted to Byte"
When I try this code:
Private Function BytesToImage(hwresponse AS Stream) As Image
Dim imgNew As Image
Dim memImage As New System.IO.MemoryStream(hwresponse)
imgNew = Image.FromStream(memImage)
Return imgNew
End Function
I get "Parameter not valid" on Image.fromStream.
I am not understanding how to take my WebResponse and pass it to the function correctly to extract the image
Related
It's a simple code
var contentHash = CryptoJS.SHA512(JSON.stringify(requestBody)).toString(CryptoJS.enc.Hex);
Also it's actually simpler. I think requestBody is just an empty string.
https://bittrex.github.io/api/v3#topic-Authentication
What I tried is to do
Dim hasher = New System.Security.Cryptography.HMACSHA512(System.Text.Encoding.UTF8.GetBytes(""))
Dim contentHash = ExchangesClass.getString(hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes("")))
Where ExchangeClass.getString is
Public Shared Function getString(sigs As Byte()) As String
Dim list = New Generic.List(Of String)
For Each b In sigs
Dim chunk = b.ToString("x2")
list.Add(chunk)
Next
Dim result = String.Concat(list)
Dim result2 = BitConverter.ToString(sigs).Replace("-", "").ToLower()
Debug.Assert(result = result2)
Return result
End Function
But that's sort of weird. Why would anyone want a hash of an empty string. Unless I am missing something. I do not see where requestBody is. Perhaps because I use only read only API of bittrex
This code works
So
var contentHash = CryptoJS.SHA512(JSON.stringify(requestBody)).toString(CryptoJS.enc.Hex);
becomes
Protected Overridable Function computeSigNoHmac(content As String) As String
Dim hasher2 = New System.Security.Cryptography.SHA512Managed() 'create hashers based on those bytes
Dim hashbytes = hasher2.ComputeHash(System.Text.Encoding.UTF8.GetBytes(content)) 'compute the hash and get bytes
Dim sighash2 = BitConverter.ToString(hashbytes).Replace("-", "").ToLower() 'turn bytes into hex string (0-9a-f)
Return sighash2
End Function
Also, for completion,
var signature = CryptoJS.HmacSHA512(preSign, apiSecret).toString(CryptoJS.enc.Hex);
Becomes
Protected Overridable Function computeSig(content As String, secret As String) As String
Dim secretinBytes = System.Text.Encoding.UTF8.GetBytes(secret) 'Turn secret hex into bytes (0-9a-f)
Dim hasher2 = New System.Security.Cryptography.HMACSHA512(secretinBytes) 'create hashers based on those bytes
'Dim hasher3 = New System.Security.Cryptography.SHA512(secretinBytes) 'create hashers based on those bytes
Dim hashbytes = hasher2.ComputeHash(System.Text.Encoding.UTF8.GetBytes(content)) 'compute the hash and get bytes
Dim sighash2 = BitConverter.ToString(hashbytes).Replace("-", "").ToLower() 'turn bytes into hex string (0-9a-f)
Return sighash2
End Function
i'm trying to follow this example to create PDF with an image
Example PDF with an Image
I'm developing with VS2013 in VB.NET (ASP.NET 3.5).
I'm getting crazy, i don't understand 2 things:
what is the name that i've to pass in the IMG tag.
The src-attribute doesn´t contain a http-Url. Instead use the prefix data:imagestream to identify the source type of the image. After the following slash the name of the resource in the manifest of the .NET library is listed.
when the END ovveride function in CustomImageTagProcessor Class is executed
I've embedded an image in the project and the manifest contains
...
}
.mresource public Test1.phone.jpg
{
// Offset: 0x00000000 Length: 0x00003E0D
}
.mresource public Test1.Resources.resources
{
// Offset: 0x00003E11 Length: 0x0000406B
}
I'm debugging step by step but never the code in the ovverride function is executed.
This is the function that produce PDF
Public Function CreateFromHtml(ByVal html As String) As Stream
Dim stream = New MemoryStream()
Using doc = New Document(PageSize.A4)
Using ms = New MemoryStream()
Using writer = PdfWriter.GetInstance(doc, ms)
writer.CloseStream = False
doc.Open()
Dim tagProcessors = CType(Tags.GetHtmlTagProcessorFactory(), DefaultTagProcessorFactory)
tagProcessors.RemoveProcessor(iTextSharp.tool.xml.html.HTML.Tag.IMG)
tagProcessors.AddProcessor(iTextSharp.tool.xml.html.HTML.Tag.IMG, New CustomImageTagProcessor())
Dim cssFiles = New CssFilesImpl()
cssFiles.Add(XMLWorkerHelper.GetInstance().GetDefaultCSS())
Dim cssResolver = New StyleAttrCSSResolver(cssFiles)
Dim charset = Encoding.UTF8
Dim context = New HtmlPipelineContext(New CssAppliersImpl(New XMLWorkerFontProvider()))
context.SetAcceptUnknown(True).AutoBookmark(True).SetTagFactory(tagProcessors)
Dim htmlPipeline = New HtmlPipeline(context, New PdfWriterPipeline(doc, writer))
Dim cssPipeline = New CssResolverPipeline(cssResolver, htmlPipeline)
Dim worker = New XMLWorker(cssPipeline, True)
Dim xmlParser = New XMLParser(True, worker, charset)
Using sr = New StringReader(html)
xmlParser.Parse(sr)
doc.Close()
ms.Position = 0
ms.CopyTo(stream)
stream.Position = 0
End Using
End Using
End Using
End Using
Return stream
End Function
And this is the Class of CustomImageTagProcessor
Imports iTextSharp.tool.xml
Imports System.Reflection
Imports iTextSharp.text
Public Class CustomImageTagProcessor
Inherits iTextSharp.tool.xml.html.Image
Public Overrides Function [End](ByVal ctx As IWorkerContext, ByVal tag As Tag, ByVal currentContent As IList(Of IElement)) As IList(Of IElement)
Dim src = String.Empty
If Not tag.Attributes.TryGetValue(iTextSharp.tool.xml.html.HTML.Attribute.SRC, src) Then Return New List(Of IElement)(1)
If String.IsNullOrEmpty(src) Then Return New List(Of IElement)(1)
If src.StartsWith("data:imagestream/", StringComparison.InvariantCultureIgnoreCase) Then
Dim name = src.Substring(src.IndexOf("/", StringComparison.InvariantCultureIgnoreCase) + 1)
Using stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name)
Return CreateElementList(ctx, tag, Image.GetInstance(stream))
End Using
End If
Return MyBase.[End](ctx, tag, currentContent)
End Function
Protected Function CreateElementList(ByVal ctx As IWorkerContext, ByVal tag As Tag, ByVal image As Image) As IList(Of IElement)
Dim htmlPipelineContext = GetHtmlPipelineContext(ctx)
Dim result = New List(Of IElement)()
Dim element = GetCssAppliers().Apply(New Chunk(CType(GetCssAppliers().Apply(image, tag, htmlPipelineContext), Image), 0, 0, True), tag, htmlPipelineContext)
result.Add(element)
Return result
End Function
End Class
Thanks so much for any helps.
I hope in you guys.
The problem was a lost
</img>
tag
Self Closed tag is not valid.
When i put tag also code inside overrided function has been executed.
Thanks so much.
I am embedding a base64String into Tinymce to display images:
<img src="blob:https://path/871bf236-3bae-472c-9f02-0bd3be19a435" alt="Desert.jpg" width="300" height="75" />
It works for small images but when it comes to large images it doesn't work and I am guessing its because the URL containing the base64String for large images hits the limit for URL browser length which I believe is around 2000 characters. Wanted to see if there was a way to shorten my base64String?
'File path of the attachment
DIM filePath = C:\path\solutions\Attachments\1\1726014c-7a2d-41b8-a79e-2acec1e8c7e0
'Converted base64String path
DIM base64URLPath = ToBase64String( ConvertToUrl(filePath)).toString
'Converts the path to a base64String
Public Function ToBase64String(filePath As String) As String
Dim aImage = New Bitmap(filePath)
Using stream = New IO.MemoryStream
Using img As Image = Image.FromFile(filePath)
If img.RawFormat.Equals(Imaging.ImageFormat.Jpeg) Then
aImage.Save(stream, Imaging.ImageFormat.Jpeg)
ElseIf img.RawFormat.Equals(Imaging.ImageFormat.Png) Then
aImage.Save(stream, Imaging.ImageFormat.Png)
ElseIf img.RawFormat.Equals(Imaging.ImageFormat.Icon) Then
aImage.Save(stream, Imaging.ImageFormat.Icon)
End If
End Using
Return Convert.ToBase64String(stream.ToArray)
End Using
End Function
'Gets the full file path
Public Function ConvertToUrl(filePath As String) As String
Dim uri = New Uri(filePath).LocalPath
Dim converted = uri
Return converted.ToString()
End Function
Based on this post I fixed the issue: Resize and Compress image to byte array without saving the new image. The ToBase64String was the only function changed and now it looks like:
'Converts the path to a base64String
Public Function ToBase64String(filePath As String) As String
Dim aImage = New Bitmap(filePath)
Dim aspectRatio As Double = aImage.Height / aImage.Width
Dim imgThumb = New Bitmap(aImage, 200, CInt(Math.Round(200 * aspectRatio)))
Using stream = New IO.MemoryStream
Using img As Image = Image.FromFile(filePath)
If img.RawFormat.Equals(Imaging.ImageFormat.Jpeg) Then
imgThumb.Save(stream, Imaging.ImageFormat.Jpeg)
ElseIf img.RawFormat.Equals(Imaging.ImageFormat.Png) Then
imgThumb.Save(stream, Imaging.ImageFormat.Png)
ElseIf img.RawFormat.Equals(Imaging.ImageFormat.Icon) Then
imgThumb.Save(stream, Imaging.ImageFormat.Icon)
End If
End Using
Return Convert.ToBase64String(stream.ToArray)
End Using
End Function
I thought this would be an easy task but I seem to have gotten lost in a rabbit hole.
I am trying to convert a class to XML and then a byte array in order to send it as the content of a HTTPWebRequest for a WCF Restful webservice. My code will return the class as XML in the Byte Array but the format is incorrect. The XML looks like this:
<?xml version="1.0" encoding="utf-8"?><Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><FirstName>Richard</FirstName><LastName>Cranium</LastName></Person>
I was attempting to use the OmitXmlDeclaration method thinking this would eliminate the extra declarations but it does not work with the xmltextwriter object and when I use the xmlwriterobject I can't determine how convert the outcome to a Byte array.
Here is my code:
Private Shared Function GenerateXMLPersonAsByte(strFirstName As String, strLastName As String) As Byte()
' This should serialize this to a byte array
Dim p As New Person()
p.FirstName = strFirstName
p.LastName = strLastName
' Want to use this with the xmlTextWriter but it does not support the property it is to be used with the XMLWriter instead
'Dim settings As XmlWriterSettings = New XmlWriterSettings()
'settings.OmitXmlDeclaration = True
'settings.ConformanceLevel = ConformanceLevel.Fragment
'settings.CloseOutput = False
' Create the XmlWriter object and write some content.
Dim mStream As New MemoryStream()
Dim ser As New XmlSerializer(GetType(Person))
Dim xmlTW As New XmlTextWriter(mStream, Encoding.UTF8)
ser.Serialize(xmlTW, p)
mStream = DirectCast(xmlTW.BaseStream, MemoryStream)
mStream.Close()
Return mStream.ToArray()
End Function
What must I do in order to get the XML with the correct opening tag?
or
How do I get the output from the XmlTextWriter object to a byte array?
I can't answer the whole question, but convert to string first
Dim myXmlString As String
Dim myStringWriter As New StringWriter()
Dim myXmlTextWriter As XmlTextWriter = New XmlTextWriter(myStringWriter)
'Write XML, and then flush the writer...
myXmlTextWriter.Flush()
'Return text from string writer...
myXmlString = myStringWriter.ToString()
'Close the Objects...
myStringWriter.Close()
myXmlTextWriter.Close()
then convert to byte using (sorry, C#, but you get the .NET call)
byte[] data = ASCIIEncoding.UTF8.GetBytes(myXmlString);
I have a problem when I download a file from a URL (This it's not my main problem), the problem comes after that.
The file that I saved from the URL can be a image, doc, PDF or ZIP.
Exists some method to know the file type when the path doesn't has the extension?
Or identify the file type from an stream?
I'm working with Visual Studio 2010 Express Edition - Framework.Net 3.5 - A Window App
Public Function DownloadFile_FromURL(ByVal URL As String, ByVal DestinationPath As String) As Boolean
DownloadFile_FromURL = False
Try
Dim vRequest As Net.HttpWebRequest
Dim vResponse As Net.HttpWebResponse
vRequest = Net.WebRequest.Create(New Uri(URL))
vRequest.Method = "GET"
vRequest.AllowAutoRedirect = True
vRequest.UseDefaultCredentials = True
vResponse = vRequest.GetResponse
If vResponse.ContentLength <> -1 Then
Dim vLen As Long = vResponse.ContentLength
Dim vWriteStream As New IO.FileStream(DestinationPath, IO.FileMode.CreateNew)
Dim vStream As IO.Stream = vResponse.GetResponseStream()
Dim vReadBytes() As Byte = New Byte(255) {}
Dim vCount As Integer = vStream.Read(vReadBytes, 0, vReadBytes.Length)
While vCount > 0
vWriteStream.Write(vReadBytes, 0, vCount)
vCount = vStream.Read(vReadBytes, 0, vReadBytes.Length)
End While
vWriteStream.Flush() : vWriteStream.Close()
vResponse.Close() : vRequest = Nothing : GCcleaner()
Dim v = System.IO.Path.GetExtension(DestinationPath)
DownloadFile_FromURL = True
End If
Catch ex As Exception
Throw New Exception(ex.mc_GetAllExceptions)
End Try
End Function
If you are using WebRequest for the download.
Dim uri As String = "http://domain.com/resource"
Dim request As HttpWebRequest = DirectCast(WebRequest.Create(uri), HttpWebRequest)
request.Method = "GET"
Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
Dim contentType = response.ContentType
' this will have the content type/ file type
You can now have a routine to save the file using a particular extension depending on the content type. for instance a content type of "image/jpeg" can be saved as *.jpg
For an Image you can load it into an Image() object and see if it throws an OutOfMemoryException -- not an image.
PDF you can read the first few bytes of it (the PDF file type info is stored there, though not sure exactly what it is at the moment).
ZIP and DOC I'm not sure about.
If you are using WebRequests you can grab the content type of the response stream. More information about the MIME/content types here: http://msdn.microsoft.com/en-us/library/ms775147.aspx