Solved

Getting Image Data From XML

Posted on 2004-08-25
3
793 Views
Last Modified: 2012-06-27
I have image data stored in an XML file using bin.base64 encoding. The xml file is as follows:
=========
<userPhotos>
<Photo>
  <UserID>1</UserID>
  <UserName>Camel-Joe</UserName>
  <PhotoContent xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64">/9j/4AAQSkZJRgABAgEBLAEsAAD/4RV2RXhpZgAA</PhotoContent>
  </Photo>
</UserPhotos>
=========

i also have a user control which takes a byte() object as input and outputs an image. When i get the xml value from the xml file and pass it to this control, i get an error of "Invalid parameter used."

======  Image User Control
    Protected Friend Sub ImageByByte(ByVal sByte As Byte())
        If (Not sByte Is Nothing) Then
            Response.ContentType = "image/jpg"
            Response.Clear()
            Dim iStream As New System.IO.MemoryStream(sByte, True)
            iStream.Write(sByte, 0, sByte.Length)
            sByte = Nothing

            Dim fullImg As Bitmap = New Bitmap(iStream)
            fullImg = System.Drawing.Image.FromStream(iStream)
            iStream = Nothing

            fullImg.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
            fullImg.Dispose()
            fullImg = Nothing
        End If
        Me.Dispose()
    End Sub
======


here's how i get the xml data and pass it to the control
=========
    Private Function xmlPhoto(ByVal userName As String) As Byte()
        Dim xDoc As New XmlDocument(), xNode As XmlNode
        Dim asc As New System.Text.ASCIIEncoding()

        Try
            xDoc = New XmlDocument()
            xDoc.Load("c:\inetpub\wwwRoot\UserPhotos.xml")
            xNode = xDoc.SelectSingleNode("//Photo[UserName = '" & userName & "']")
            xmlPhoto = asc.GetBytes(xNode.Item("PhotoContent").InnerText)
        Finally
            asc = Nothing
            xDoc = Nothing
            xNode = Nothing
        End Try
    End Function
=========


If i pass the byte data to the control directly from a sql table (where images are also stored) there's no problem. so i'm doing something wrong in grabbing the image data from xml.

xNode.Item("PhotoContent").InnerText returns the correct xml element value.
xmlPhoto.GetType returns System.Byte[].  
xmlPhoto.length also returns an integer value >  0.

Any help would be greatly appreciated. thanks.


0
Comment
Question by:jklNYC
  • 2
3 Comments
 
LVL 26

Expert Comment

by:rdcpro
ID: 11896962
Use nodeTypedValue, something more or less like:

            xNode = xDoc.SelectSingleNode("//Photo[UserName = '" & userName & "']")
            xmlPhoto = xNode.nodeTypedValue

Darshan Singh had a good article on doing this:

http://www.perfectxml.com/articles/xml/binary.asp

Regards,
Mike Sharp
0
 
LVL 2

Author Comment

by:jklNYC
ID: 11897042
Mike,

Yeah I've tried to use the nodetypedvalue and it doesn't work. i get this error on compile
"img.aspx.vb(82): 'nodetypedvalue' is not a member of 'System.Xml.XmlNode'."

I've read that article, and I am unable to use the following lines:

Dim oXMLDOMDoc As New MSXML2.DOMDocument40
Dim oNode As MSXML2.IXMLDOMNode

The server won't recognize those object declarations. Am I missing something on the server? Do i need to install another XML library object?

.jkl.

0
 
LVL 26

Accepted Solution

by:
rdcpro earned 250 total points
ID: 11897251
Oh, I didn't know you were using .NET.  You might be able to use the XmlTextReader.ReadBase64 method, which reads a base64 encoding stream and fills a byte array buffer.  It returns the number of bytes written to the buffer.

Public Function ReadBase64( _
   ByVal array() As Byte, _
   ByVal offset As Integer, _
   ByVal len As Integer _
) As Integer

Parameters

  array
    The array of characters that serves as the buffer to which the text contents are written.
  offset
    The zero-based index into the array specifying where the method can begin to write to the buffer.
  len
    The number of bytes to write into the buffer.
  Return Value
    The number of bytes written to the buffer.

Remarks

Like ReadChars, this method can be called successively to read large streams of embedded text. It decodes Base64 content and returns the decoded binary bytes (for example, an inline Base64 encoded GIF image) into the buffer. See RFC 1521. (You can obtain RFCs from the Request for Comments Web site at http://www.rfc-editor.org)




Here's a C# example that does basically the same thing:


XmlTextReader reader = new XmlTextReader(filename);
while(reader.Read()) {
  if (reader.LocalName == "element") {
    byte[] bytes = new byte[1000];
    int n = reader.ReadBase64(bytes, 0, 1000);
    string buf = Encoding.Unicode.GetString(bytes);
    Console.WriteLine(buf.Substring(0,n));
  }
}
reader.Close();

And, a VB.NET example from MSDN:

[Visual Basic, C#, C++] The following example reads a file containing Base64 and BinHex data.

[Visual Basic]
Option Explicit
Option Strict

Imports System
Imports System.IO
Imports System.Xml
Imports Microsoft.VisualBasic

Public Class Sample
   Private Const filename As String = "binary.xml"
   
   
   Public Shared Sub Main()
      Dim reader As XmlTextReader = Nothing
      Dim i As Integer

      Try
         reader = New XmlTextReader(filename)
         reader.WhitespaceHandling = WhitespaceHandling.None        

         ' Read the file. Stop at the Base64 element.        
         While reader.Read()
            If "Base64" = reader.Name Then
               Exit While
            End If
         End While

         ' Read the Base64 data. Write the decoded
         ' bytes to the console.
         Console.WriteLine("Reading base64... ")
         Dim base64len As Integer = 0
         Dim base64(1000) As Byte
         Do
            base64len = reader.ReadBase64(base64, 0, 50)
            For i = 0 To base64len - 1
               Console.Write(base64(i))
            Next i
         Loop While (reader.Name = "Base64")

         ' Read the BinHex data. Write the decoded
         ' bytes to the console.
         Console.WriteLine(ControlChars.CrLf & "Reading binhex....")
         Dim binhexlen As Integer = 0
         Dim binhex(1000) As Byte
         binhexlen = reader.ReadBinHex(binhex, 0, 50)
         Do
            binhexlen = reader.ReadBinHex(binhex, 0, 50)
            For i = 0 To binhexlen - 1
               Console.Write(binhex(i))
            Next i
         Loop While (reader.Name = "BinHex")
     
      Finally
         Console.WriteLine()
         Console.WriteLine("Processing of the file {0} complete.", filename)
         If Not (reader Is Nothing) Then
            reader.Close()
         End If
      End Try
   End Sub 'Main
End Class 'Sample


Regards,
Mike Sharp
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Parse data from XMLtype data in Oracle SQL 5 75
SharePoint 2013 Blog Template 2 35
Checkbox and ListView in Android Layout 4 56
c# code 19 69
The Problem How to write an Xquery that works like a SQL outer join, providing placeholders for absent data on the outer side?  I give a bit more background at the end. The situation expressed as relational data Let’s work through this.  I’ve …
The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now