C#显示GBK点阵字模
acmilan2016/06/07软件综合 IP:四川

ASCII、GB2312、GBK、GB18030、UTF-8的关系:

  • ASCII是一个7位编码,只能表示英文字符,由于电脑字节为8位,因此产生了GB2312、GBK、GB18030、UTF-8等扩展码。
  • GB2312是一个双字节扩展码,将区码高位加0xA0作为第一个字节,位码加0xA0作为第二个字节,显示汉字的编码。
  • GBK扩展了GB2312的范围,首字节可以是0x81-0xFE,尾字节可以是0x40-0x7E,0x80-0xFE。
  • GB18030扩展了GBK,增加了四字节编码(第二、第四字节可以是0x30-0x39)以便覆盖所有Unicode字符。
  • UTF-8和上述编码除了都兼容ASCII外,没有任何关系,是一种完全不同的Unicode编码形式。

显示效果(方便起见,没有实现半角显示):

gbk16.png gbk24.png

C#代码如下,如有错误欢迎指出。

<code class="language-C#">using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace gbkzk
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            gbk16zm = File.ReadAllBytes("gbk16.bin");
            gbk24zm = File.ReadAllBytes("gbk24.bin");
        }

        private byte[] gbk16zm;
        private byte[] gbk24zm;

        // 计算GBK偏移量
        private int gbkoffset(byte blb, byte bhb) // byte == unsigned char
        {
            uint bl = blb;
            uint bh = bhb;
            uint offset = 0;
            if (bh > 0x7F) bh--; // 去掉7F一条线
            if (bl >= 0x81 && bl <= 190 0xa0) gbk 3: 81~a0 190*32="6080" { offset="(bl" - 0x81) * + (bh 0x40); } else if (bl>= 0xA1 && bl <= 1 94 0xa7) gbk 1: a1~a7 94*7="658" { offset="(bl" - 0xa1) * + (bh 6080; 注意此处要加1 } else if (bl>= 0xA8 && bl <= 190 6080 0xa9) gbk 1与gbk 5合并区 a8 a9 190*2="380" { offset="(bl" - 0xa8) * + (bh 0x40) 658; } else if (bl>= 0xAA && bl <= 4 96 658 6080 0xaf) gbk aa~af 96*6="576" { offset="(bl" - 0xaa) * + (bh 0x40) 380; } else if (bl>= 0xB0 && bl <= 190 380 658 6080 0xf7) gbk 4与gbk 2合并区 b0~f7 190*72="13680" { offset="(bl" - 0xb0) * + (bh 0x40) 576; } else if (bl>= 0xF8 && bl <= 1="=" 4 96 380 576 658 6080 0xfe) gbk f8~fe 96*7="672" { offset="(bl" - 0xf8) * + (bh 0x40) 13680; } return (int)offset; 取得字符的字模 private byte[] getgbkzm(byte[] gbkzm, int pt, byte bl, bh) size="pt" pt 8; 计算字模大小 size; 计算偏移量 zm="new" byte[size]; array.copy(gbkzm, offset, zm, 0, size); 取这个字的字模 zm; 扫描字模 bool scanzm(byte[] x, y) bitoff="y" x; 由坐标计算总位偏移 byteoff="bitoff" 字节偏移 bitshift="(7" % 8); 位偏移(从高位开始) ((zm[byteoff]>> bitshift) & 1); // 取所需位
        }

        // 绘制字模
        private void drawzm(Graphics g, byte[] zm, int pt, int x, int y)
        {
            Bitmap bmp = new Bitmap(pt, pt); // 先在位图上绘制
            for (int i = 0; i < pt; i++)
            {
                for (int j = 0; j < pt; j++)
                {
                    bool val = scanzm(zm, pt, j, i); // 扫描字模
                    bmp.SetPixel(j, i, val ? Color.Black : Color.White); // 设置位图点的颜色
                }
            }
            g.DrawImage(bmp, x, y); // 绘制位图
        }

        // 绘制字符串(只实现了全角字符)
        private void drawstring(byte[] str, Graphics g, byte[] gbkzm, int pt)
        {
            byte bl = 0;
            byte bh = 0;
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] >= 0x81 && str[i] <= 0xfe && i < str.length) { 全角字符 bl="str[i];" bh="str[i" + 1]; 取得字模 byte[] zm="getgbkzm(gbkzm," pt, bl, bh); 计算坐标 int x="i" * pt 2; y="0;" 绘制字模 drawzm(g, zm, x, y); 跳过尾字节 i++; } else 不实现半角英文字符显示 continue; private void button1_click(object sender, eventargs e) txt="Encoding.GetEncoding(936).GetBytes(textBox1.Text);" graphics g="pictureBox1.CreateGraphics();" g.clear(color.white); drawstring(txt, g, gbk16zm, 16); button2_click(object gbk24zm, 24); code></=></=></=></=></=></=></=></code>

所用GBK字模:
attachment icon gbkzm1624.rar 1.23MB RAR 42次下载

[修改于 8年6个月前 - 2016/06/07 15:33:45]

来自:计算机科学 / 软件综合
1
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
acmilan 作者
8年6个月前 修改于 8年6个月前 IP:四川
821095

GB2312和GBK存在的价值在于,它们非常容易实现,而Unicode则不是那么容易实现。

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
acmilan
进士 学者 笔友
文章
461
回复
2934
学术分
4
2009/05/30注册,5年10个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}