views:

285

answers:

1

Hi All. 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;
        }
    }
}
+2  A: 

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.

Mehrdad Afshari
thanks, i just tried that and no change. it's still not displaying the image
baeltazor
@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?
Mehrdad Afshari
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?
baeltazor
@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.
Mehrdad Afshari
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.
baeltazor
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.
Mehrdad Afshari
@Mehradad, how would I go about using your last updated code mixed in with my existing xml code?
baeltazor
@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.
Mehrdad Afshari