反序列化从 BMFont 工具导出的 XML 时出错
Error deserializing XML exported from BMFont tool
我正在尝试使用以下示例:http://www.faqwhosebug.com/answered/using-a-bmp-image-as-font-in-monogame
这个概念似乎很合理。我正在使用由建议的工具生成的 .fnt。根据 classes 中使用的 [Serialization],它看起来格式正确并且有意义。
但是,每次我 运行 代码都会收到此错误:“System.Xml.dll
中发生了 'System.InvalidOperationException' 类型的未处理异常
附加信息:XML 文档 (1, 1) 中存在错误。"
我狂热地查看了 StackExchange 和 google,并在来这里发布我的问题之前尝试了很多东西。我在下面的 FontLoader class 内发表的评论中仍有许多这些尝试的混乱遗留问题,我正在修改以尝试解决该问题。无论如何切片,它都会给出相同的错误,甚至更糟。
public class FontLoader
{
public static FontFile Load(String filename)
{
/* XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
TextReader textReader = new StreamReader(Encoding.UTF8.GetBytes(filename).ToString());
FontFile file = (FontFile)deserializer.Deserialize(textReader);
textReader.Close();
return file;*/
byte[] bytes = Encoding.UTF8.GetBytes(System.IO.File.ReadAllText(filename));
FontFile myInstance = null;
using (MemoryStream memStream = new MemoryStream(bytes))
{
XmlSerializer tokenSerializer = new XmlSerializer(typeof(FontFile));
myInstance = (FontFile)tokenSerializer.Deserialize(memStream);
Console.WriteLine(myInstance);
return myInstance;
}
/*
XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
TextReader textReader = new StreamReader(filename);
FontFile file = (FontFile)deserializer.Deserialize(textReader);
textReader.Close();
return file;*/
/* var xml = System.IO.File.ReadAllText(filename);
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
XmlSerializer serializer = new XmlSerializer(typeof(FontFile));
FontFile file = (FontFile)serializer.Deserialize(stream);
return file;
}*/
/* var writer = new StringWriter();
var serializer = new XmlSerializer((filename.GetType()));
serializer.Serialize(writer, filename);
string xml = writer.ToString();
return xml;*/
}
}
我使用的字体是Arial,作为测试,应该可以使用。它以这些行开头:
info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32 x=155 y=75 width=3 height=1 xoffset=-1 yoffset=31 xadvance=8 page=0 chnl=15
然后是具有相同结构的许多 "char" 行的 contineus,其次是字距调整行,然后是 "kerning" 行的 bunce,如下所示,具有相同的结构:
kernings count=91
kerning first=32 second=65 amount=-2
如果序列化最终出现问题,我为发布而道歉,但我没有看到它。如果有人有解决方案,请告诉我。谢谢。
自从您提到的那个答案写下来后,有一些事情发生了变化。您可以使用 MonoGame.Extended library to do exactly what you're trying to do. I wrote a detailed blog post 前一段时间的相关内容,而不是自己编写。
您需要做的第一件事是 install the MonoGame.Extended NuGet package。 运行 在程序包管理器控制台中执行以下命令。
Install-Package MonoGame.Extended -Pre
一旦安装完成,您的包文件夹中就会有几个 DLL。其中之一将需要由 MonoGame 管道工具引用。最简单的方法是在文本编辑器中手动编辑 Content.mgcb
文件。像这样添加参考行,但一定要匹配当前版本。
#-------------------------------- References --------------------------------#
/reference:..\..\packages\MonoGame.Extended.0.3.44-alpha\lib\MonoGame.Extended.Content.Pipeline.dll
最后,您可以将字体文件和纹理添加到 MonoGame 管道工具并像加载任何其他内容一样加载。
_bitmapFont = Content.Load<BitmapFont>("my-font");
然后使用精灵批处理绘制它
_spriteBatch.Begin();
_spriteBatch.DrawString(_bitmapFont, "Hello World", new Vector2(100, 200), Color.Red);
_spriteBatch.End();
如果您确实想自己编写它,您可以查看 implementation from MonoGame.Extended,因为它是开源的。
从你原来的问题来看,这个问题其实很明显,但和你一样,我一开始忽略了这个问题。
在您向我发送 .fnt
文件后,我几乎立即发现了这个问题,因为我将它与我之前导出的文件进行了比较。问题是您以错误的格式导出文件。正如您在问题中所说,您的文件如下所示:
info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32 x=155 y=75 width=3 height=1 xoffset=-1 yoffset=31 xadvance=8 page=0 chnl=15
但它应该看起来更像这样:
<?xml version="1.0"?>
<font>
<info face="Arial" size="32" bold="1" italic="0" charset="" unicode="1" stretchH="100" smooth="1" aa="1" padding="0,0,0,0" spacing="1,1" outline="1"/>
<common lineHeight="32" base="26" scaleW="256" scaleH="256" pages="1" packed="0" alphaChnl="1" redChnl="0" greenChnl="0" blueChnl="0"/>
<pages>
<page id="0" file="arial_0.png" />
</pages>
<chars count="191">
将它们并排比较后,差异就很明显了。第一个文件是纯文本,第二个文件是 XML。它发生在我们最好的人身上:)
无论如何,要修复它,您只需在 BMFont 工具中将文件格式设置为 XML。
- 单击选项
- 单击导出选项
- 单击对话框底部附近的 XML 单选按钮
然后再次导出文件。
我正在尝试使用以下示例:http://www.faqwhosebug.com/answered/using-a-bmp-image-as-font-in-monogame
这个概念似乎很合理。我正在使用由建议的工具生成的 .fnt。根据 classes 中使用的 [Serialization],它看起来格式正确并且有意义。
但是,每次我 运行 代码都会收到此错误:“System.Xml.dll
中发生了 'System.InvalidOperationException' 类型的未处理异常附加信息:XML 文档 (1, 1) 中存在错误。"
我狂热地查看了 StackExchange 和 google,并在来这里发布我的问题之前尝试了很多东西。我在下面的 FontLoader class 内发表的评论中仍有许多这些尝试的混乱遗留问题,我正在修改以尝试解决该问题。无论如何切片,它都会给出相同的错误,甚至更糟。
public class FontLoader
{
public static FontFile Load(String filename)
{
/* XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
TextReader textReader = new StreamReader(Encoding.UTF8.GetBytes(filename).ToString());
FontFile file = (FontFile)deserializer.Deserialize(textReader);
textReader.Close();
return file;*/
byte[] bytes = Encoding.UTF8.GetBytes(System.IO.File.ReadAllText(filename));
FontFile myInstance = null;
using (MemoryStream memStream = new MemoryStream(bytes))
{
XmlSerializer tokenSerializer = new XmlSerializer(typeof(FontFile));
myInstance = (FontFile)tokenSerializer.Deserialize(memStream);
Console.WriteLine(myInstance);
return myInstance;
}
/*
XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
TextReader textReader = new StreamReader(filename);
FontFile file = (FontFile)deserializer.Deserialize(textReader);
textReader.Close();
return file;*/
/* var xml = System.IO.File.ReadAllText(filename);
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
XmlSerializer serializer = new XmlSerializer(typeof(FontFile));
FontFile file = (FontFile)serializer.Deserialize(stream);
return file;
}*/
/* var writer = new StringWriter();
var serializer = new XmlSerializer((filename.GetType()));
serializer.Serialize(writer, filename);
string xml = writer.ToString();
return xml;*/
}
}
我使用的字体是Arial,作为测试,应该可以使用。它以这些行开头:
info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32 x=155 y=75 width=3 height=1 xoffset=-1 yoffset=31 xadvance=8 page=0 chnl=15
然后是具有相同结构的许多 "char" 行的 contineus,其次是字距调整行,然后是 "kerning" 行的 bunce,如下所示,具有相同的结构:
kernings count=91
kerning first=32 second=65 amount=-2
如果序列化最终出现问题,我为发布而道歉,但我没有看到它。如果有人有解决方案,请告诉我。谢谢。
自从您提到的那个答案写下来后,有一些事情发生了变化。您可以使用 MonoGame.Extended library to do exactly what you're trying to do. I wrote a detailed blog post 前一段时间的相关内容,而不是自己编写。
您需要做的第一件事是 install the MonoGame.Extended NuGet package。 运行 在程序包管理器控制台中执行以下命令。
Install-Package MonoGame.Extended -Pre
一旦安装完成,您的包文件夹中就会有几个 DLL。其中之一将需要由 MonoGame 管道工具引用。最简单的方法是在文本编辑器中手动编辑 Content.mgcb
文件。像这样添加参考行,但一定要匹配当前版本。
#-------------------------------- References --------------------------------#
/reference:..\..\packages\MonoGame.Extended.0.3.44-alpha\lib\MonoGame.Extended.Content.Pipeline.dll
最后,您可以将字体文件和纹理添加到 MonoGame 管道工具并像加载任何其他内容一样加载。
_bitmapFont = Content.Load<BitmapFont>("my-font");
然后使用精灵批处理绘制它
_spriteBatch.Begin();
_spriteBatch.DrawString(_bitmapFont, "Hello World", new Vector2(100, 200), Color.Red);
_spriteBatch.End();
如果您确实想自己编写它,您可以查看 implementation from MonoGame.Extended,因为它是开源的。
从你原来的问题来看,这个问题其实很明显,但和你一样,我一开始忽略了这个问题。
在您向我发送 .fnt
文件后,我几乎立即发现了这个问题,因为我将它与我之前导出的文件进行了比较。问题是您以错误的格式导出文件。正如您在问题中所说,您的文件如下所示:
info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32 x=155 y=75 width=3 height=1 xoffset=-1 yoffset=31 xadvance=8 page=0 chnl=15
但它应该看起来更像这样:
<?xml version="1.0"?>
<font>
<info face="Arial" size="32" bold="1" italic="0" charset="" unicode="1" stretchH="100" smooth="1" aa="1" padding="0,0,0,0" spacing="1,1" outline="1"/>
<common lineHeight="32" base="26" scaleW="256" scaleH="256" pages="1" packed="0" alphaChnl="1" redChnl="0" greenChnl="0" blueChnl="0"/>
<pages>
<page id="0" file="arial_0.png" />
</pages>
<chars count="191">
将它们并排比较后,差异就很明显了。第一个文件是纯文本,第二个文件是 XML。它发生在我们最好的人身上:)
无论如何,要修复它,您只需在 BMFont 工具中将文件格式设置为 XML。
- 单击选项
- 单击导出选项
- 单击对话框底部附近的 XML 单选按钮
然后再次导出文件。