【问题标题】:Loading image data from xml file从 xml 文件加载图像数据
【发布时间】:2010-02-08 19:05:30
【问题描述】:

我有以下从 xml 文件加载数据的代码。我已经做了很长一段时间了,但没有那个代码了,这不起作用。 (我可以成功将图像数据写入文件。但是加载它并转换为图像对象不起作用):

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

和...:

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;
}

有人能解释一下为什么我的表单上没有显示转换后的图像吗?我根本没有收到任何错误...图像只是不显示。

谢谢

贝尔

更新


以下代码用于将图像数据写入 xml 文件:
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;
    }
}

...这就是从 xml 文件加载(好吧,无论如何都会尝试)图像并将其显示在表单上的内容:

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);
}

下面是 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>

更新

这是我用来打开/读取/处理 xml 文件的代码。另请注意,从文件中正确读取所有其他控件(例如标签链接标签等)并成功显示在表单上。只是 PictureBox 没有出现:

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;
        }
    }
}

【问题讨论】:

  • 你确定图片不会太小? (通过放置断点并检查image 变量来检查宽度/高度)
  • 我尝试改变大小,仍然没有区别。我将发布实际读取 xml 文件并创建图像的代码,如果有帮助的话
  • @baeltazor:我认为您应该使用调试器检查您的完整应用程序。这个问题看起来与这些事情无关。您是否尝试在事件处理程序中放置断点?真的开火了吗?由于我发布的小应用程序运行良好。
  • 事件处理程序正在触发,因为正如您在上面看到的,我的窗口的标题栏文本在文件被打开到应用程序后更改为文件名
  • @baeltazor:base64String 传递给函数是否正确? (使用 VS 调试器检查)。

标签: c# winforms image base64


【解决方案1】:

您应该在Write 调用之后立即重置MemoryStream 的位置:

ms.Position = 0;

调用Write 将自动增加职位。因此,在不重置位置的情况下,流已经在末尾,Image.FromStream 将无法从中读取(它从当前位置开始读取)。


更新

我看到您的Write 电话根本没有必要。您应该直接将MemoryStream 初始化为byte[],并将其作为构造函数传递:

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

如果失败,您从 XML 读取的数据可能有问题。


更新:

我的测试应用程序适用于您的图像:

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);
    }
}

检查您的事件处理程序、XML 加载过程和其他内容。这部分代码看起来不错。

【讨论】:

  • 谢谢,我刚试过,没有任何改变。它仍然没有显示图像
  • @baeltazor:查看代码后,我发现您做错了。为什么要在流已经填满时写入?
  • 我不太确定...这是我第二次不得不从 xml 加载图像数据,所以我真的不知道如何正确执行。您能否建议我应该如何以正确的方式去做?
  • @baeltazor:我已经更新了答案。如果您可以正确读取 base64 字符串,则应该可以。你得到什么例外?否则,如果问题是从 XML 读取,您应该发布它的结构供我们查看。
  • 感谢您的帮助。我刚刚尝试了更新的代码,但它不起作用。我根本没有任何例外。图像只是根本不显示。我正在更新我的问题,请参阅问题底部。
猜你喜欢
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
相关资源
最近更新 更多