在Monogame中使用BMP图像作为字体 [英] Using a BMP image as font in Monogame

查看:405
本文介绍了在Monogame中使用BMP图像作为字体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以使用BMP图像加载自定义字体..



我在网上看到了一个由微软提供的解决方案,但是我一直在获取内容当试图运行这个解决方案时,会发生一个负载异常。



看起来这个过去与XNA一起工作,但对于Monogame来说可能不是这样。
$ b

我想要我自己的自定义字体,因为这个字体不会被预先安装在客户端的计算机上。



我已经查看了SpriteFont Converter的XNB文件,这不是我想要的解决方案。

<任何帮助将不胜感激,谢谢

解决方案

经过一段时间的研究负荷,我最终找到一个解决方案在线。这里是一个链接到教程: http://www.craftworkgames。 com / blog / tutorial-bmfont-rendering-with-monogame / b
$ b

这个方法需要你下载一个名为bmFont的软件: http://www.angelcode.com/products/bmfont/



使用这个软件,你将得到一个你的Font输出为2个文件:

$ ol

  • .fnt文件,用于模式纹理

  • .png文件,这是实际的字符。

    为了使这些文件与你的单项目一起工作(也可以与XNA工作,我想),你需要添加这个类到你的项目(注意:您将需要更改名称空间):

      // ---- AngelCode BmFont XML序列化程序---------------------- 
    // ----由DeadlyDan @ deadlydan @ gmail。 com -------------------
    // ----没有许可限制,你可以使用。 ----
    // ---- ----致谢http://www.angelcode.com/ -----------------

    使用系统;
    使用System.IO;
    使用System.Xml.Serialization;
    using System.Collections.Generic;
    使用Microsoft.Xna.Framework;
    使用Microsoft.Xna.Framework.Graphics;
    使用Microsoft.Xna.Framework.Content;

    命名空间仪表板
    {
    公共类BmFont {

    字符串fontFilePath;
    FontFile fontFile;
    Texture2D fontTexture;
    FontRenderer _fontRenderer;

    public BmFont(String fontTexture,String png,ContentManager c){
    fontFilePath = Path.Combine(c.RootDirectory,fontTexture);
    fontFile = FontLoader.Load(fontFilePath);
    this.fontTexture = c.Load< Texture2D>(png);
    _fontRenderer = new FontRenderer(fontFile,this.fontTexture);

    $ b $ public void draw(String message,Vector2 pos,SpriteBatch _spriteBatch){
    _fontRenderer.DrawText(_spriteBatch,(int)pos.X,(int)pos.Y , 信息);




    public class FontRenderer
    {

    public static FontFile Load(Stream stream)
    {
    XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
    FontFile file =(FontFile)deserializer.Deserialize(stream);
    返回文件;

    $ b $ public FontRenderer(FontFile fontFile,Texture2D fontTexture)
    {
    _fontFile = fontFile;
    _texture = fontTexture;
    _characterMap = new Dictionary< char,FontChar>();

    foreach(var fontCharacter in _fontFile.Chars)
    {
    char c =(char)fontCharacter.ID;
    _characterMap.Add(c,fontCharacter);
    }
    }

    私人字典< char,FontChar> _characterMap;
    private FontFile _fontFile;
    private Texture2D _texture;
    public void DrawText(SpriteBatch spriteBatch,int x,int y,string text)
    {
    int dx = x;
    int dy = y;
    foreach(char c in text)
    {
    FontChar fc;
    if(_characterMap.TryGetValue(c,out fc))
    {
    var sourceRectangle = new Rectangle(fc.X,fc.Y,fc.Width,fc.Height);
    var position = new Vector2(dx + fc.XOffset,dy + fc.YOffset);

    spriteBatch.Draw(_texture,position,sourceRectangle,Color.White);
    dx + = fc.XAdvance;





    [可序列化]
    [XmlRoot(font)]
    public class FontFile
    {
    [XmlElement(info)]
    public FontInfo Info
    {
    get;
    set;

    $ b $ [XmlElement(common)]
    public FontCommon Common
    {
    get;
    set;
    }

    [XmlArray(pages)]
    [XmlArrayItem(page)]
    public List< FontPage>页面
    {
    get;
    set;
    }

    [XmlArray(chars)]
    [XmlArrayItem(char)]
    public List< FontChar>字符
    {
    get;
    set;
    }

    [XmlArray(kernings)]
    [XmlArrayItem(kerning)]
    public List< FontKerning> Kernings
    {
    get;
    set;



    [Serializable]
    public class FontInfo
    {
    [XmlAttribute(face)]
    public字符串面
    {
    get;
    set;
    }

    [XmlAttribute(size)]
    public Int32 Size
    {
    get;
    set;

    $ b $ [XmlAttribute(bold)]
    public Int32 Bold
    {
    get;
    set;

    $ b $ [XmlAttribute(italic)]
    public Int32 Italic
    {
    get;
    set;

    $ b $ [XmlAttribute(charset)]
    public String CharSet
    {
    get;
    set;

    $ b $ [XmlAttribute(unicode)]
    public Int32 Unicode
    {
    get;
    set;
    }

    [XmlAttribute(stretchH)]
    public Int32 StretchHeight
    {
    get;
    set;
    }

    [XmlAttribute(smooth)]
    public Int32 Smooth
    {
    get;
    set;
    }

    [XmlAttribute(aa)]
    public Int32 SuperSampling
    {
    get;
    set;
    }

    私人矩形_Padding;
    [XmlAttribute(padding)]
    public String Padding
    {
    get
    {
    return _Padding.X +,+ _Padding.Y +,+ _Padding.Width +,+ _Padding.Height;
    }
    set
    {
    String [] padding = value.Split(',');
    _Padding = new Rectangle(Convert.ToInt32(padding [0]),Convert.ToInt32(padding [1]),Convert.ToInt32(padding [2]),Convert.ToInt32(padding [3]));
    }
    }

    私人点_Spacing;
    [XmlAttribute(spacing)]
    public String Spacing
    {
    get
    {
    return _Spacing.X +,+ _Spacing.Y ;
    }
    set
    {
    String [] spacing = value.Split(',');
    _Spacing = new Point(Convert.ToInt32(spacing [0]),Convert.ToInt32(spacing [1]));


    $ b [XmlAttribute(outline)]
    public Int32 OutLine
    {
    get;
    set;



    [Serializable]
    public class FontCommon
    {
    [XmlAttribute(lineHeight)]
    public Int32 LineHeight
    {
    get;
    set;

    $ b $ [XmlAttribute(base)]
    public Int32 Base
    {
    get;
    set;

    $ b $ [XmlAttribute(scaleW)]
    public Int32 ScaleW
    {
    get;
    set;
    }

    [XmlAttribute(scaleH)]
    public Int32 ScaleH
    {
    get;
    set;

    $ b $ [XmlAttribute(pages)]
    public Int32 Pages
    {
    get;
    set;

    $ b $ [XmlAttribute(packed)]
    public Int32 Packed
    {
    get;
    set;
    }

    [XmlAttribute(alphaChnl)]
    public Int32 AlphaChannel
    {
    get;
    set;

    $ b $ [XmlAttribute(redChnl)]
    public Int32 RedChannel
    {
    get;
    set;

    $ b $ [XmlAttribute(greenChnl)]
    public Int32 GreenChannel
    {
    get;
    set;
    }

    [XmlAttribute(blueChnl)]
    public Int32 BlueChannel
    {
    get;
    set;



    [Serializable]
    public class FontPage
    {
    [XmlAttribute(id)]
    public Int32 ID
    {
    get;
    set;

    $ b $ [XmlAttribute(file)]
    public String File
    {
    get;
    set;



    [Serializable]
    public class FontChar
    {
    [XmlAttribute(id)]
    public Int32 ID
    {
    get;
    set;
    }

    [XmlAttribute(x)]
    public Int32 X
    {
    get;
    set;
    }

    [XmlAttribute(y)]
    public Int32 Y
    {
    get;
    set;

    $ b $ [XmlAttribute(width)]
    public Int32 Width
    {
    get;
    set;
    }

    [XmlAttribute(height)]
    public Int32 Height
    {
    get;
    set;

    $ b $ [XmlAttribute(xoffset)]
    public Int32 XOffset
    {
    get;
    set;
    }

    [XmlAttribute(yoffset)]
    public Int32 YOffset
    {
    get;
    set;
    }

    [XmlAttribute(xadvance)]
    public Int32 XAdvance
    {
    get;
    set;

    $ b $ [XmlAttribute(page)]
    public Int32 Page
    {
    get;
    set;
    }

    [XmlAttribute(chnl)]
    public Int32 Channel
    {
    get;
    set;



    [Serializable]
    public class FontKerning
    {
    [XmlAttribute(first)]
    public Int32首先
    {
    get;
    set;

    $ b $ [XmlAttribute(second)]
    public Int32 Second
    {
    get;
    set;

    $ b $ [XmlAttribute(amount)]
    public Int32 Amount
    {
    get;
    set;



    public class FontLoader
    {
    public static FontFile Load(String filename)
    {
    XmlSerializer deserializer =新的XmlSerializer(typeof(FontFile));
    TextReader textReader = new StreamReader(filename);
    FontFile file =(FontFile)deserializer.Deserialize(textReader);
    textReader.Close();
    返回文件;





    我稍微修改了这个类以面向对象的方式实现。以下是在主Game.cs文件中如何使用此类与您的自定义字体。

    对于这个例子,我有由BmFonts软件生成的 time_0.png time.fnt 文件。它们是字体Avenir Next的结果Condensed that I want to use。

      public class Game1:Game 
    {
    //用于游戏工作的图形变量
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    BmFont fontTime;


    $ b public Game1()
    {
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory =Content;
    graphics.IsFullScreen = true;


    protected override void LoadContent()
    {
    //创建一个新的SpriteBatch,可以用来绘制纹理。
    spriteBatch =新的SpriteBatch(GraphicsDevice);
    fontTime = new BmFont(time.fnt,time_0.png,this.Content);


    protected override void Draw(GameTime gameTime)
    {
    graphics.GraphicsDevice.Clear(Color.CornflowerBlue);



    spriteBatch.Begin();
    fontTime.draw(DateTime.Now.ToString(HH mm),new Vector2(100,50)),spriteBatch);
    spriteBatch.End();
    base.Draw(gameTime);
    }



    }

    你走了。现在你应该没问题,看看它为你自己工作。
    难度较大的部分会随着字体大小而变化,因为您需要为每个字体大小生成一个文件。



    尽管技术为您提供了直接嵌入字体的可能性,而不需要最终用户在他的计算机上安装它(曾经崩溃)。

    Enjoy,
    凯文


    Is there a way to load a custom font using a BMP image..

    I have seen a solution online by Microsoft providing this, but i keep on getting content-load exception when trying to run this solution.

    It seems like this used to work with XNA but might not be the case anymore with Monogame.

    I want my own custom font, since this font won't be pre-installed on the computer of the client.

    I already looked at XNB files from SpriteFont Converter, and that is not the solution i wish to aim for.

    Any help will be appreciated, thanks

    解决方案

    After a Long while load of research, I ended up on finding a solution online. Here is a link to the tutorial : http://www.craftworkgames.com/blog/tutorial-bmfont-rendering-with-monogame/

    This methods require you to download a software called bmFont : http://www.angelcode.com/products/bmfont/

    With this software, you will receive an output of your Font as 2 files :

    1. .fnt file, used for the pattern in the texture
    2. .png file, which is the actual characters.

    In order to make those files work with your monoproject (could work also with XNA i suppose), you need to add this class to your project (Note : You will need to change the namespace) :

    // ---- AngelCode BmFont XML serializer ----------------------
    // ---- By DeadlyDan @ deadlydan@gmail.com -------------------
    // ---- There's no license restrictions, use as you will. ----
    // ---- Credits to http://www.angelcode.com/ -----------------
    
    using System;
    using System.IO;
    using System.Xml.Serialization;
    using System.Collections.Generic;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Content;
    
    namespace Dashboard
    {
        public class BmFont {
    
            String fontFilePath;
            FontFile fontFile;
            Texture2D fontTexture;
            FontRenderer _fontRenderer;
    
            public BmFont(String fontTexture, String png, ContentManager c) {
                fontFilePath = Path.Combine(c.RootDirectory, fontTexture);
                fontFile = FontLoader.Load(fontFilePath);
                this.fontTexture = c.Load<Texture2D>(png);
                _fontRenderer = new FontRenderer(fontFile, this.fontTexture);
            }
    
            public void draw(String message, Vector2 pos, SpriteBatch _spriteBatch) {
                _fontRenderer.DrawText(_spriteBatch, (int)pos.X, (int)pos.Y, message);
            }
    
        }
    
    
        public class FontRenderer
        {
    
            public static FontFile Load(Stream stream)
            {
                XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
                FontFile file = (FontFile) deserializer.Deserialize(stream);
                return file;
            }
    
            public FontRenderer (FontFile fontFile, Texture2D fontTexture)
            {
                _fontFile = fontFile;
                _texture = fontTexture;
                _characterMap = new Dictionary<char, FontChar>();
    
                foreach(var fontCharacter in _fontFile.Chars)
                {
                    char c = (char)fontCharacter.ID;
                    _characterMap.Add(c, fontCharacter);
                }
            }
    
            private Dictionary<char, FontChar> _characterMap;
            private FontFile _fontFile;
            private Texture2D _texture;
            public void DrawText(SpriteBatch spriteBatch, int x, int y, string text)
            {
                int dx = x;
                int dy = y;
                foreach(char c in text)
                {
                    FontChar fc;
                    if(_characterMap.TryGetValue(c, out fc))
                    {
                        var sourceRectangle = new Rectangle(fc.X, fc.Y, fc.Width, fc.Height);
                        var position = new Vector2(dx + fc.XOffset, dy + fc.YOffset);
    
                        spriteBatch.Draw(_texture, position, sourceRectangle, Color.White);
                        dx += fc.XAdvance;
                    }
                }
            }
        }
    
    
        [Serializable]
        [XmlRoot ( "font" )]
        public class FontFile
        {
            [XmlElement ( "info" )]
            public FontInfo Info
            {
                get;
                set;
            }
    
            [XmlElement ( "common" )]
            public FontCommon Common
            {
                get;
                set;
            }
    
            [XmlArray ( "pages" )]
            [XmlArrayItem ( "page" )]
            public List<FontPage> Pages
            {
                get;
                set;
            }
    
            [XmlArray ( "chars" )]
            [XmlArrayItem ( "char" )]
            public List<FontChar> Chars
            {
                get;
                set;
            }
    
            [XmlArray ( "kernings" )]
            [XmlArrayItem ( "kerning" )]
            public List<FontKerning> Kernings
            {
                get;
                set;
            }
        }
    
        [Serializable]
        public class FontInfo
        {
            [XmlAttribute ( "face" )]
            public String Face
            {
                get;
                set;
            }
    
            [XmlAttribute ( "size" )]
            public Int32 Size
            {
                get;
                set;
            }
    
            [XmlAttribute ( "bold" )]
            public Int32 Bold
            {
                get;
                set;
            }
    
            [XmlAttribute ( "italic" )]
            public Int32 Italic
            {
                get;
                set;
            }
    
            [XmlAttribute ( "charset" )]
            public String CharSet
            {
                get;
                set;
            }
    
            [XmlAttribute ( "unicode" )]
            public Int32 Unicode
            {
                get;
                set;
            }
    
            [XmlAttribute ( "stretchH" )]
            public Int32 StretchHeight
            {
                get;
                set;
            }
    
            [XmlAttribute ( "smooth" )]
            public Int32 Smooth
            {
                get;
                set;
            }
    
            [XmlAttribute ( "aa" )]
            public Int32 SuperSampling
            {
                get;
                set;
            }
    
            private Rectangle _Padding;
            [XmlAttribute ( "padding" )]
            public String Padding
            {
                get
                {
                    return _Padding.X + "," + _Padding.Y + "," + _Padding.Width + "," + _Padding.Height;
                }
                set
                {
                    String[] padding = value.Split ( ',' );
                    _Padding = new Rectangle ( Convert.ToInt32 ( padding[0] ), Convert.ToInt32 ( padding[1] ), Convert.ToInt32 ( padding[2] ), Convert.ToInt32 ( padding[3] ) );
                }
            }
    
            private Point _Spacing;
            [XmlAttribute ( "spacing" )]
            public String Spacing
            {
                get
                {
                    return _Spacing.X + "," + _Spacing.Y;
                }
                set
                {
                    String[] spacing = value.Split ( ',' );
                    _Spacing = new Point ( Convert.ToInt32 ( spacing[0] ), Convert.ToInt32 ( spacing[1] ) );
                }
            }
    
            [XmlAttribute ( "outline" )]
            public Int32 OutLine
            {
                get;
                set;
            }
        }
    
        [Serializable]
        public class FontCommon
        {
            [XmlAttribute ( "lineHeight" )]
            public Int32 LineHeight
            {
                get;
                set;
            }
    
            [XmlAttribute ( "base" )]
            public Int32 Base
            {
                get;
                set;
            }
    
            [XmlAttribute ( "scaleW" )]
            public Int32 ScaleW
            {
                get;
                set;
            }
    
            [XmlAttribute ( "scaleH" )]
            public Int32 ScaleH
            {
                get;
                set;
            }
    
            [XmlAttribute ( "pages" )]
            public Int32 Pages
            {
                get;
                set;
            }
    
            [XmlAttribute ( "packed" )]
            public Int32 Packed
            {
                get;
                set;
            }
    
            [XmlAttribute ( "alphaChnl" )]
            public Int32 AlphaChannel
            {
                get;
                set;
            }
    
            [XmlAttribute ( "redChnl" )]
            public Int32 RedChannel
            {
                get;
                set;
            }
    
            [XmlAttribute ( "greenChnl" )]
            public Int32 GreenChannel
            {
                get;
                set;
            }
    
            [XmlAttribute ( "blueChnl" )]
            public Int32 BlueChannel
            {
                get;
                set;
            }
        }
    
        [Serializable]
        public class FontPage
        {
            [XmlAttribute ( "id" )]
            public Int32 ID
            {
                get;
                set;
            }
    
            [XmlAttribute ( "file" )]
            public String File
            {
                get;
                set;
            }
        }
    
        [Serializable]
        public class FontChar
        {
            [XmlAttribute ( "id" )]
            public Int32 ID
            {
                get;
                set;
            }
    
            [XmlAttribute ( "x" )]
            public Int32 X
            {
                get;
                set;
            }
    
            [XmlAttribute ( "y" )]
            public Int32 Y
            {
                get;
                set;
            }
    
            [XmlAttribute ( "width" )]
            public Int32 Width
            {
                get;
                set;
            }
    
            [XmlAttribute ( "height" )]
            public Int32 Height
            {
                get;
                set;
            }
    
            [XmlAttribute ( "xoffset" )]
            public Int32 XOffset
            {
                get;
                set;
            }
    
            [XmlAttribute ( "yoffset" )]
            public Int32 YOffset
            {
                get;
                set;
            }
    
            [XmlAttribute ( "xadvance" )]
            public Int32 XAdvance
            {
                get;
                set;
            }
    
            [XmlAttribute ( "page" )]
            public Int32 Page
            {
                get;
                set;
            }
    
            [XmlAttribute ( "chnl" )]
            public Int32 Channel
            {
                get;
                set;
            }
        }
    
        [Serializable]
        public class FontKerning
        {
            [XmlAttribute ( "first" )]
            public Int32 First
            {
                get;
                set;
            }
    
            [XmlAttribute ( "second" )]
            public Int32 Second
            {
                get;
                set;
            }
    
            [XmlAttribute ( "amount" )]
            public Int32 Amount
            {
                get;
                set;
            }
        }
    
        public class FontLoader
        {
            public static FontFile Load ( String filename )
            {
                XmlSerializer deserializer = new XmlSerializer ( typeof ( FontFile ) );
                TextReader textReader = new StreamReader ( filename );
                FontFile file = ( FontFile ) deserializer.Deserialize ( textReader );
                textReader.Close ( );
                return file;
            }
        }
    }
    

    I have slightly modified this class in order to implement it in a Object Oriented way. Here is how you make use of this class with your Custom font in your main Game.cs file.

    For this example, i have the files time_0.png and time.fnt produced by the software BmFonts. They are the result of the font Avenir Next Condensed that I wanted to use.

    public class Game1 : Game
    {
        // Graphic variables used for the game to work
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        BmFont fontTime;
    
    
    
        public Game1 ()
        {
            graphics = new GraphicsDeviceManager (this);
            Content.RootDirectory = "Content";              
            graphics.IsFullScreen = true;       
        }
    
        protected override void LoadContent ()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch (GraphicsDevice);
            fontTime = new BmFont ("time.fnt", "time_0.png", this.Content);
        }
    
        protected override void Draw (GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear (Color.CornflowerBlue);
    
    
    
            spriteBatch.Begin();
                fontTime.draw (DateTime.Now.ToString("HH mm"), new Vector2 (100, 50)), spriteBatch);
            spriteBatch.End();
            base.Draw (gameTime);
        }
    
    
    
    }
    

    There you go. Now you should be all fine, see it working for yourself. The hard part will be playing around with your font size, since you'll need to generate a file for each font size you want.

    Although, this techniques offer you to possibility to directly embbed a font without requiering the end user to have it on his computer installed (Which used to crash).

    Enjoy, Kevin

    这篇关于在Monogame中使用BMP图像作为字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆