首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

用C#兑现一个字模点阵提取程序

2012-07-05 
用C#实现一个字模点阵提取程序本文源代码位于:http://download.csdn.net/detail/caozhy/4401532程序比较简

用C#实现一个字模点阵提取程序
本文源代码位于:http://download.csdn.net/detail/caozhy/4401532

程序比较简单,已经给出了主要源代码,十分希望对程序感兴趣的同学自己动手编译调试。实在懒得动脑动手的再去下载。故而设置了10分下载分。

上大学的时候搞单片机实验,大家都知道要提取字库。

很多人还在研究UCDOS下的那些点阵文件,其实使用C#,可以很方便地写一个程序提取Windows字体。

优点是,代码实现起来非常容易。并且可以借助Windows上庞大的TTF字体资源,实现各种各样的字体,不再局限UCDOS中几种有限的字体。还可以实现很多特殊效果,因为Windows的字体就是绘图嘛。

以前用VB写过一个,写了好久才写成。最近有人问,给了他思路,他却还是搞不定,我就很郁闷了,这个很难么?

自己写了下,几行代码就出来了。主要是LINQ实在太简洁了,没办法。

代码如下:

C# code
private void button3_Click(object sender, EventArgs e){    //显示按钮    var data = textBox2.Text.Select(x => x == '1').Concat(Enumerable.Repeat(false, 256))        .Take(256).ToArray();    Graphics g = pictureBox1.CreateGraphics();    for (int i = 0; i < 16; i++)    {        for (int j = 0; j < 16; j++)        {            Brush brush = data[j * 16 + i] ? Brushes.Blue : Brushes.White;            g.FillRectangle(brush, new Rectangle() { X = i * 16, Y = j * 16, Width = 16, Height = 16 });        }    }}private void button1_Click(object sender, EventArgs e){    //字体设置    FontDialog fd = new FontDialog() { Font = textBox1.Font, FontMustExist = true };    if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)    {        textBox1.Font = fd.Font;    }}private void button2_Click(object sender, EventArgs e){    //产生字模    Bitmap bmp = new Bitmap(16, 16);    Graphics g = Graphics.FromImage(bmp);    g.FillRectangle(Brushes.White, new Rectangle() { X = 0, Y = 0, Height = 16, Width = 16 });    g.DrawString(textBox1.Text, textBox1.Font, Brushes.Black, new PointF() { X = Convert.ToSingle(domainUpDown1.Text), Y = Convert.ToSingle(domainUpDown2.Text) });    textBox2.Text = string.Join("", Enumerable.Range(0, 256).Select(a => new { x = a % 16, y = a / 16 })        .Select(x => bmp.GetPixel(x.x, x.y).GetBrightness() > 0.5f ? "0" : "1"));    button3.PerformClick();}private void textBox1_TextChanged(object sender, EventArgs e){    //输入文字的文本框    textBox1.Text = textBox1.Text.Length > 0 ? textBox1.Text.Substring(textBox1.Text.Length - 1) : "";    textBox1.SelectionStart = textBox1.Text.Length;}private void domainUpDown1_SelectedItemChanged(object sender, EventArgs e){    //微调,用来设置偏移    button2.PerformClick();}private void domainUpDown2_SelectedItemChanged(object sender, EventArgs e){    button2.PerformClick();}


运行图

Windows 7的字体效果更好。


[解决办法]
ImageData[
 Binarize[Rasterize[
Style["啊", FontSize -> 12, FontFamily -> "Tahoma"]]]]



{{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 0, 1, 0, 0, 0, 
1, 0, 0, 0, 1}, {0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1}, {0, 1, 0, 1, 
0, 1, 0, 0, 0, 0, 1, 1}, {0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1}, {0, 
1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1}, {0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 
1}, {0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1}, {0, 0, 0, 1, 0, 1, 0, 1, 
1, 0, 1, 1}, {0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1}, {1, 1, 1, 1, 0, 
1, 1, 1, 1, 0, 1, 1}, {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1}}
[解决办法]
应该有人和我一样看不懂linq,所以我复刻了一个非linq的。。



来代码,为了对比,原来的linq在注释里,下面是代替的方法。

C# code
// 修改字体private void button1_Click(object sender, EventArgs e){    if (fontDialog1.ShowDialog() == DialogResult.OK)        textBox1.Font = fontDialog1.Font;}// 生成字模private void button2_Click(object sender, EventArgs e){    if (string.IsNullOrEmpty(textBox1.Text))        return;    Bitmap bmp = new Bitmap(16, 16);    Graphics g = Graphics.FromImage(bmp);    //g.FillRectangle(Brushes.White, new Rectangle() { X = 0, Y = 0, Height = 16, Width = 16 });    g.Clear(Color.White);    //g.DrawString(textBox1.Text, textBox1.Font, Brushes.Black, new PointF() { X = Convert.ToSingle(domainUpDown1.Text), Y = Convert.ToSingle(domainUpDown2.Text) });    g.DrawString(textBox1.Text, textBox1.Font, Brushes.Black, (float)numericUpDown1.Value, (float)numericUpDown2.Value);    //textBox2.Text = string.Join("", Enumerable.Range(0, 256).Select(a => new { x = a % 16, y = a / 16 }).Select(x => bmp.GetPixel(x.x, x.y).GetBrightness() > 0.5f ? "0" : "1"));    StringBuilder sb = new StringBuilder();    for (int y = 0; y < 16; y++)    {        for (int x = 0; x < 16; x++)        {            if (bmp.GetPixel(x, y).GetBrightness() > 0.5f)                sb.Append("0");            else                sb.Append("1");        }    }    textBox2.Text = sb.ToString();    button3.PerformClick();}// 显示private void button3_Click(object sender, EventArgs e){    //var data = textBox2.Text.Select(x => x == '1').Concat(Enumerable.Repeat(false, 256)).Take(256).ToArray();    bool[] data = new bool[256];    for (int i = 0; i < 256; i++)    {        data[i] = textBox2.Text[i] == '1';    }    Graphics g = pictureBox1.CreateGraphics();    for (int i = 0; i < 16; i++)    {        for (int j = 0; j < 16; j++)        {            Brush brush = data[j * 16 + i] ? Brushes.Blue : Brushes.White;            //g.FillRectangle(brush, new Rectangle() { X = i * 16, Y = j * 16, Width = 16, Height = 16 });            g.FillRectangle(brush, i * 16, j * 16, 16, 16);        }    }} 


[解决办法]
你好,运行了下,在显示字模的消息中有错,是string.Join的错误,它的第二个参数是string[]。但是源码中是string。求指教。
[解决办法]

探讨
应该有人和我一样看不懂linq,所以我复刻了一个非linq的。。



来代码,为了对比,原来的linq在注释里,下面是代替的方法。


C# code
// 修改字体
private void button1_Click(object sender, EventArgs e)
{
if (fontDialog1.ShowDialog() == DialogResul……

[解决办法]

生成字库的时候,还要把实际使用的多种方式都考虑进去,一般生成的汉字与使用时是逆序的。

显示汉字的时候,有的是横向显示,从上到下,然后从左到右,还有的则是从下到上,然后从左到右方便。

也有一些液晶屏是要竖向显示的,每个字还要根据屏幕的特性考虑bit序。

另外还要考虑字体的识别问题,比如O和0一定要在显示的时候有差别,这就要求有简单的编辑功能。

除了能够字库,还要能够按需求生成符合某些规范的字库,比如生成GB18030的字库。

最后就是除了标准的字库,还要能够对图片进行处理,以为显示logo等功能。

[解决办法]
提取为矢量的“多Polyline集合”数据,再存到数据库中备用,会更好!
[解决办法]
资源没释放呢,可不好哦
探讨

应该有人和我一样看不懂linq,所以我复刻了一个非linq的。。



来代码,为了对比,原来的linq在注释里,下面是代替的方法。

C# code
// 修改字体
private void button1_Click(object sender, EventArgs e)
{
if (fontDialog1.ShowDialog() == DialogResult.OK……

热点排行