在XML文档中插入图像

本文关键字:插入 图像 文档 XML | 更新日期: 2023-09-27 18:03:39

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

我试着遵循其他人的建议(像这个),但我没有得到正确的结果;我得到的只是文件中的原始字节字符串输出。

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

有人能帮我吗?由于

在XML文档中插入图像

我浏览了链接问题中的所有链接,找到了你一直在使用的那个。问题似乎是,在您的程序中,您没有像Chuck指出的那样,在那里放置代码来将xml文件中的数据转换回图像。您提供的代码很可能正确地保存了数据,但如果您使用的是通用编辑器(如Notepad或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文件时看到的字符串是已编码的图像数据。您可以将其视为原始数据。

在我的测试用例中,我创建了一个纹理图集(将动画的所有帧按给定顺序平铺在单个图像文件中),在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编码进行编码。

现在将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 not,我重复一下 not XmlElement。我知道博客上说这是XmlElement,但正如你已经发现的那样,两者之间有很大的区别。第一行实际上已经完全重写,以利用Imagexml代码,所以这应该有一点帮助。它所做的是获取作为字符串存储的图像数据。如果你注意到,我把它放在一个Attribute。许多人认为这是正确的做法,我同意他们的看法。将数据放在Attribute之外可能会产生一些微妙的错误。在这个例子中,我能够从相同的XElement检索我的动画元数据。下一行将字符串转换为字节数组,您可以想象,这更像是在计算机上构造实际图像的方式。最后一行是在MemoryStream中包装图像数据,现在是字节数组格式,并创建一个要返回的新Bitmap实例。

如果您想要使用代码,只需获取在更新中编写的代码部分并将它们放在public class文件中。