Loading image data from xml file

11,358

You should reset the position of MemoryStream right after the Write call:

ms.Position = 0;

Calls to Write will increase the position automatically. Consequently, without resetting the position, the stream will already be at the end and Image.FromStream will fail to read from it (it starts reading at the current position).


Update

I'm seeing that your Write call is fundamentally unnecessary. You should simply initialize the MemoryStream with the byte[] directly by passing it as the constructor:

byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes);
return Image.FromStream(ms, true);

If this fails, something is probably wrong with the data you're reading from XML.


Update:

My test application works with your image:

using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;
class Program
{
    static void Main(string[] args)
    {
        string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<cs>
  <PictureBox Content=""Qk1mAgAAAAAAALYAAAAoAAAAFgAAABIAAAABAAgAAAAAAAAAAADEDgAAxA4AACAAAAAgAAAA/////8z///8z////AMD////MzP9mzMz/M8zM/zOZzP/AwMD/vLy8/2aZmf8zmZn/M2aZ/5CQkP9sbGz/ZmZm/zMzZv9BQUH/AAAA/8DAwAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8TEw0PDw8PDRMTExMTExMTExMTExMTAAATDw8JCQkJEQ0TExAQEBAQEBMTExMTAAAODQAPCQEJCRENEAUFBQUFBRAQExMTAAAOAQ8NDwkBAAkRAwMCAgICBQULEBMTAAANDw0ADw0NAAkRAwICAgICAgUFCxATAAATDwEPDw8JAAkRAwICAgUFBQIFBRATAAATDQ8PCQEAEREDAwICAgICAgICBQsQAAATExMPDw8PEQMDAgcHBwsLCwwMBQsQAAATEw8BAA8BABEDAgcCAgICAgIFDAsQAAATEw8BDxMPAREDAwIFBQUFBQUFBQsQAAATDwEADxMPAQARAwICAgIKCgYEBAsQAAATDwEPExMQDwERAwIGBAQCBgASAAsQAAATDQ8NExMTDRENAgIGEgACAgYAABATAAATExMTExMTEAMDAgIAAAACAgYKChATAAATExMTExMTExADAwIKBgYCAgIGEBMTAAATExMTExMTExMQEAMCCgoCAhAQExMTAAATExMTExMTExMTExAQEBAQEBMTExMTAAATExMTExMTExMTExMTExMTExMTExMTAAA="" LocationX=""446"" LocationY=""125"" />
</cs>";
        var x = XDocument.Parse(xml);
        var s = x.Descendants("PictureBox").First().Attribute("Content").Value;
        var f = new Form();
        PictureBox p = new PictureBox();
        p.Dock = DockStyle.Fill;
        f.Controls.Add(p);
        p.Image = Base64ToImage(s);
        Application.Run(f);
    }

    static Image Base64ToImage(string base64String)
    {
        byte[] imageBytes = Convert.FromBase64String(base64String);
        MemoryStream ms = new MemoryStream(imageBytes);
        return Image.FromStream(ms, true);
    }
}

Check your event handlers, XML load process, and other stuff. This part of code looks fine.

Share:
11,358
jay_t55
Author by

jay_t55

Updated on June 27, 2022

Comments

  • jay_t55
    jay_t55 almost 2 years

    I have the following code that loads data from an xml file. I've done this quite a while back but don't have that code anymore, and this isn't working. (I can successfully write image data to file. But loading it and converting to image object isn't working):

    p.Image = Base64ToImage(controlTag.Attributes("Content").First().Value); // i call this on button click.
    

    and...:

    public Image Base64ToImage(string base64String)
    {
        // Convert Base64 String to byte[]
        byte[] imageBytes = Convert.FromBase64String(base64String);
        MemoryStream ms = new MemoryStream(imageBytes, 0,
          imageBytes.Length);
    
        // Convert byte[] to Image
        ms.Write(imageBytes, 0, imageBytes.Length);
        Image image = Image.FromStream(ms, true);
        return image;
    }
    

    Can somebody please explain why this isn't displaying the converted image on my Form? I don't get any errors at all... The images just don't show up.

    Thank you

    bael

    UPDATE


    The following code is what's used to write the image data to the xml file:

    public string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            // Convert Image to byte[]
            image.Save(ms, format);
            byte[] imageBytes = ms.ToArray();
    
            // Convert byte[] to Base64 String
            string base64String = Convert.ToBase64String(imageBytes);
            return base64String;
        }
    }
    

    ...And this is what loads (well, trys to anyway) the image from the xml file and displays it on the Form:

    public Image Base64ToImage(string base64String)
    {
        // Convert Base64 String to byte[]
        byte[] imageBytes = Convert.FromBase64String(base64String);
        MemoryStream ms = new MemoryStream(imageBytes);
        return Image.FromStream(ms, true);
    }
    

    And here is what the xml file looks like:

    <?xml version="1.0" encoding="utf-8"?>
    <cs>
      <PictureBox Content="Qk1mAgAAAAAAALYAAAAoAAAAFgAAABIAAAABAAgAAAAAAAAAAADEDgAAxA4AACAAAAAgAAAA/////8z///8z////AMD////MzP9mzMz/M8zM/zOZzP/AwMD/vLy8/2aZmf8zmZn/M2aZ/5CQkP9sbGz/ZmZm/zMzZv9BQUH/AAAA/8DAwAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8TEw0PDw8PDRMTExMTExMTExMTExMTAAATDw8JCQkJEQ0TExAQEBAQEBMTExMTAAAODQAPCQEJCRENEAUFBQUFBRAQExMTAAAOAQ8NDwkBAAkRAwMCAgICBQULEBMTAAANDw0ADw0NAAkRAwICAgICAgUFCxATAAATDwEPDw8JAAkRAwICAgUFBQIFBRATAAATDQ8PCQEAEREDAwICAgICAgICBQsQAAATExMPDw8PEQMDAgcHBwsLCwwMBQsQAAATEw8BAA8BABEDAgcCAgICAgIFDAsQAAATEw8BDxMPAREDAwIFBQUFBQUFBQsQAAATDwEADxMPAQARAwICAgIKCgYEBAsQAAATDwEPExMQDwERAwIGBAQCBgASAAsQAAATDQ8NExMTDRENAgIGEgACAgYAABATAAATExMTExMTEAMDAgIAAAACAgYKChATAAATExMTExMTExADAwIKBgYCAgIGEBMTAAATExMTExMTExMQEAMCCgoCAhAQExMTAAATExMTExMTExMTExAQEBAQEBMTExMTAAATExMTExMTExMTExMTExMTExMTExMTAAA=" LocationX="446" LocationY="125" />
    </cs>
    

    UPDATE

    Here is the code that I use to open/read/process the xml file. Also note that all other controls (such as labels linklabels etc) are properly read from the file and successfully displayed on the Form. It's just the PictureBox's that don't show up:

    private void toolStripButton1392_Click(object sender, EventArgs e)
    {
        OpenFileDialog o = new OpenFileDialog();
    
        o.Filter =
            "T Multimedia Format (*.mf)|*.mf|" +
            "Word Document (*.docx)|*.docx|" +
            "PDF Document (*.pdf)|*.pdf|" +
            "Text FIle (*.txt)|*.txt";
        o.Title = "T 11 - Open Document";
    
        using (o)
        {
            if (o.ShowDialog() == DialogResult.OK)
            {
                foreach (var controlTag in XDocument.Load(o.FileName).Root.Elements())
                {
                    var controlType = Type.GetType(string.Format("System.Windows.Forms.{0}, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", controlTag.Name.LocalName), false);
                    if (controlType == null || !typeof(Control).IsAssignableFrom(controlType))
                    {
                        continue;
                    }
    
                    var control = (Control)Activator.CreateInstance(controlType);
                    control.Text = controlTag.Attributes("Content").First().Value;
    
                    try
                    {
                        control.ForeColor = Color.FromArgb(
                            int.Parse(controlTag.Attributes("A").First().Value),
                            int.Parse(controlTag.Attributes("R").First().Value),
                            int.Parse(controlTag.Attributes("G").First().Value),
                            int.Parse(controlTag.Attributes("B").First().Value));
    
                        Font font = FromString(controlTag.Attributes("Font").First().Value);
                        control.Font = font;
                    }
                    catch { continue; }
    
                    control.BackColor = Color.Transparent;
    
                    control.MouseDown += new MouseEventHandler(control_MouseDown);
                    control.MouseMove += new MouseEventHandler(control_MouseMove);
                    control.MouseUp += new MouseEventHandler(control_MouseUp);
                    control.MouseClick += new MouseEventHandler(control_MouseClick);
                    control.MouseDoubleClick += new MouseEventHandler(control_MouseDoubleClick);
    
                    Type t = control.GetType();
                    if (t.Name == "Label")
                    {
                        Control c = control;
                        c = control;
                        Label label = (Label)control;
                        label.AutoSize = true;
                        label.Location = new Point(
                            Convert.ToInt32(controlTag.Attributes("LocationX").First().Value),
                            Convert.ToInt32(controlTag.Attributes("LocationY").First().Value));
    
                        Canvas.Controls.Add(label);
    
                        // handlers.
                        label.MouseDown += new MouseEventHandler(label_MouseDown);
                        label.MouseMove += new MouseEventHandler(label_MouseMove);
                        label.MouseUp += new MouseEventHandler(label_MouseUp);
                        label.MouseClick += new MouseEventHandler(label_MouseClick);
                        label.MouseDoubleClick += new MouseEventHandler(label_MouseDoubleClick);
                    }
                    else if (t.Name == "LinkLabel")
                    {
                        Control c = control;
    
                        LinkLabel link = new LinkLabel();
                        link.AutoSize = true;
                        link.Location = new Point(
                            Convert.ToInt32(controlTag.Attributes("LocationX").First().Value),
                            Convert.ToInt32(controlTag.Attributes("LocationY").First().Value));
    
                        Canvas.Controls.Add(link);
    
                        // Add handlers.
                        link.MouseDown += new MouseEventHandler(link_MouseDown);
                        link.MouseMove += new MouseEventHandler(link_MouseMove);
                        link.MouseUp += new MouseEventHandler(link_MouseUp);
                        link.MouseClick += new MouseEventHandler(link_MouseClick);
                        link.MouseDoubleClick += new MouseEventHandler(link_MouseDoubleClick);
                    }
                    else if (t.Name == "PictureBox")
                    {
                        Control c = control;
                        c = control;
                        PictureBox p = new PictureBox();
    
                        p.Image = Base64ToImage(controlTag.Attributes("Content").First().Value);
                        p.InitialImage = Base64ToImage(controlTag.Attributes("Content").First().Value);
                        p.Size = new Size(50, 50);
                        p.Location = new Point(
                            Convert.ToInt32(controlTag.Attributes("LocationX").First().Value),
                            Convert.ToInt32(controlTag.Attributes("LocationY").First().Value));
    
                        Canvas.Controls.Add(p);
    
                        // Add handlers.
                        p.MouseDown += new MouseEventHandler(p_MouseDown);
                        p.MouseMove += new MouseEventHandler(p_MouseMove);
                        p.MouseUp += new MouseEventHandler(p_MouseUp);
                        p.MouseClick += new MouseEventHandler(p_MouseClick);
                        p.MouseDoubleClick += new MouseEventHandler(p_MouseDoubleClick);
                    }
                }
                this.Text = "T 11 - " + o.FileName;
            }
        }
    }
    
  • jay_t55
    jay_t55 about 14 years
    thanks, i just tried that and no change. it's still not displaying the image
  • mmx
    mmx about 14 years
    @baeltazor: Upon looking at code, I'm seeing that you're doing this wrong. Why are you writing to the stream when it's already filled?
  • jay_t55
    jay_t55 about 14 years
    I'm not too sure... This is the second time I've ever had to load image data from xml, so I don't really know how to do it properly. Could you please kindly suggest how I should go about doing it the right way?
  • mmx
    mmx about 14 years
    @baeltazor: I've updated the answer. If you can read the base64 string correctly, this should work. What exception are you getting? Otherwise, if the problem is reading from XML, you should post its structure for us to see.
  • jay_t55
    jay_t55 about 14 years
    Thank you for your help. I just tried the updated code, but it didn't work. I'm not getting any exceptions at all. The image just simply does not display. I am updating my question, please see bottom of question.
  • mmx
    mmx about 14 years
    You might consider placing a breakpoint on the first line to see if base64string is read correctly (manually compare it with the XML) and see if the image is read correctly.
  • jay_t55
    jay_t55 about 14 years
    @Mehradad, how would I go about using your last updated code mixed in with my existing xml code?
  • mmx
    mmx about 14 years
    @baeltazor: I didn't say you should mix it up. I wanted to show that the image loading part is working correctly. Apparently something is wrong in a different part of your app.