将图像插入XML文档

时间:2014-05-15 16:40:24

标签: c# xml image

我尝试使用C#将条形码的图像插入到XML文档中;该方法将路径传递给图像,然后将其与其他数据一起插入到XML文件中。

我已尝试过其他人的推荐(例如this one),但我没有得到正确的结果;我得到的只是文件中的原始字节串输出。

        byte[] bytes = File.ReadAllBytes(barcodePath);
        string barcodeString = Convert.ToBase64String(bytes);

        //find barcode position
        XmlNodeList barcodePossiblesList = doc.SelectNodes("//w:t", namespaceManager);

        foreach(XmlNode n in barcodePossiblesList)
        {
            if(n.InnerText == "Barcode")
            {
                n.InnerText = barcodeString;
            }
        }

我也尝试了以下内容,但我仍然得到了相同的结果:

Bitmap bmp = new Bitmap(imageFileName);
TypeConverter converter = TypeDescriptor.GetConverter(typeof(Bitmap));
XElement img = new XElement("image",
Convert.ToBase64String(
    (byte[])converter.ConvertTo(bmp, typeof(byte[]))));
element.Add(img);

任何人都可以帮助我吗?感谢

1 个答案:

答案 0 :(得分:1)

我浏览了链接问题中的所有链接,找到了您正在使用的链接。似乎问题在于,在你的程序中,你没有将代码放在那里将xml文件中的数据转换回图像,就像Chuck指出的那样。您提供的代码很可能正确保存数据,但如果您使用的是通用编辑器(如记事本或Visual Studio内置的XML编辑器),您将只看到与位图像素数据等效的字符串。由于您尝试将数据转换回图像,因此只需使用标题Reading the Image from the XML file下的帖子中提供的代码即可。即,

string val = currentXml.Element("image").Value;
byte[] bytes = Convert.FromBase64String(val);
MemoryStream mem = new MemoryStream(bytes);
Bitmap bmp2 = new Bitmap(mem);

这是上述代码的一行代码。也取自链接网站。

Bitmap bmp = new Bitmap(new MemoryStream(Convert.FromBase64String(currentXml.Element("image").Value)));

更新:我测试了OP以及本文中提供的代码。它确实有效。

更新2:在回答您的问题时,我决定扩展博客发布的内容。我理解它,但我确实知道LINQ-to-XML,这消除了当博客作出术语错误时路上的任何颠簸。

首先,整个过程是从图像中获取像素数据并将其放在xml文件中。这样,图像可以与其他东西一起发送。在纯文本编辑器或xml编辑器中打开xml文件时看到的字符串是已编码的图像数据。您可以将其视为原始数据。

在我的测试用例中,我创建了一个texture atlas(通过按给定顺序平铺放置在单个图像文件中的动画的所有帧),在xml文件中放置一些元数据(水平帧数)和垂直)。当在经验的背景下解释其中的一些时,以上是针对某些背景的。

我现在要指出的是using directives用来使这一切全部工作:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Xml.Linq;

我将逐步将图像转换为xml代码。以下是修改为静态方法的代码:

public static XElement ImageToXElement(System.Drawing.Image image)
{
    Bitmap bitmap = new Bitmap(image);
    TypeConverter converter = TypeDescriptor.GetConverter(typeof(Bitmap));
    return new XElement("Image",
        new XAttribute("PixelData",
            Convert.ToBase64String(
                (byte[])converter.ConvertTo(bmp, typeof(byte[]))));
}

第一行非常自我解释。最后一行,返回行都与LINQ-to-XML有关。它首先创建一个带有用于存储数据的属性的xml节点。我这样设置,以防你想要包含一些其他数据。在调整我的测试用例时,我将动画元数据放在那里。最后一部分将Image参数中的像素数据转换为使用base 64 encoding编码的字符串。

现在将Image数据从xml转换为Bitmap格式:

public static Bitmap XmlToBitmap(XElement xmlData)
{
    string imageAsBase64String = xmlData.Attribute("PixelData").Value;
    byte[] imageAsBytes = Convert.FromBase64String(val);
    Bitmap result;
    using (MemoryStream imageAsMemoryStream = new MemoryStream(bytes))
    {
        result = new Bitmap(imageAsMemoryStream);
    }

    return result;
}

我希望这个版本比我原先发布的复制代码更好地解释自己,如果有的话,太棒了!以下是对正在发生的事情的一点解释,这也将成为理解LINQ-to-XML的速成课程。首先,这使用XElement而不是,我重复XmlElement。我知道这位博客发布了它是XmlElement,但正如你已经发现的那样,2之间存在很大差异。第一行实际上已被完全重写以利用{{1}到Image代码,所以这应该有点帮助。它正在做的是获取存储为字符串的图像数据。如果您注意到,我将其放在xml内。许多人认为这是正确的做法,我同意他们的看法。通过将数据放在Attribute之外,可以创建一些微妙的错误。在这个例子中,我能够从同一个Attribute检索我的动画元数据。下一行将字符串转换为字节数组,如您所想,更像是在计算机上构建实际图像。最后一行将图像数据(现在采用字节数组格式)包装在XElement中,并创建要返回的新MemoryStream实例。

如果您想要使用代码,只需抓取更新中编写的代码部分并将其放在Bitmap文件中。