提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


文章目录

  • 前言
  • 一、佳明手表APP开发过程简介
  • 二、做个简单的个性化——在英文版写几个汉字
  • 1.MonkeyC 图形处理
  • 2.获得汉字点阵字模数据
  • 3.MonkeyC 汉字输出函数
  • Build 和部署
  • Build
  • 部署
  • 总结



前言

佳明手表是可以编程的,一直想试一试。由于GPT的缘故(居然真的是), 我随便问了问,佳明手表怎么开发啊?它给出了方法和佳明网站的开发文档的URL。我一看,居然比想象的简单。这个简单体现在两方面,首先个人申请是可以的,第二个是开发和手机开发类似。而且它还提供了很多例子,OK,走起来。


一、佳明手表APP开发过程简介

(本来想盗用GPT的回答,但是悲剧了,好像让用了)
大约是:
1、安装佳明手表开发的SDK
2、安装VsCode
3、安装MonkeyC 插件

就这三步!
下面给出 佳明SDK 的URL,所有开发介绍上面都有。当然,直接访问是不行的。

佳明开发者佳明手表开发

二、做个简单的个性化——在英文版写几个汉字

1.MonkeyC 图形处理

MonkeyC 的语法是一个综合体,里面有C的影子,有java的影子,好像也有Python的影子。不管怎样,它支持简单的画图功能,这就可以了。SDK 管理器会下载很多例子,其中和表盘相关的有两个,一个是动画表盘一个是模拟表盘。有了这个两个例子,基本上就可以探索到表盘开发的脉络了。
它的图形处理,支持图片加载和各种优化技术,例如内存缓冲图片,以及绘图区域控制等等。当然,一般的点线形的基本绘图功能,它是支持的。由此,要实现在英文版上输出汉字,也就成为可能。这个思想很简单,就是把汉字画出来。
MonkeyC 的绘图功能和C++的类似,也是通过DC来实现的。DC 是 device context 的简写,而这个设备上下文或者设备相关到底是什么呢?笔者虽然使用多年了,也没搞清楚。它的解释大致如下:

The device context (also called simply the “DC”) is really just a data structure maintained internally by GDI. A device context is associated with a particular display device, such as a video display or a printer. For a video display, a device context is usually associated with a particular window on the display.

从这段话可以看出,这个是和设备相关的一个数据结构,或者对象。由于没有进行过windows的底层开发,因此想很清楚的理解它的物理含义可能不太容易。因此,我们就直接使用吧。
较真的同学,自己查查msdn吧。

一个简单的MonkeyC 绘图代码如下:

var X = 10;
	var Y = 10;
    dc.drawPoint(X, Y);

改代码在 坐标(X,Y)处以当前的颜色绘制一个点,我们将使用这个函数把汉字画出来。

2.获得汉字点阵字模数据

最早的汉字系统是点阵字库, 常用的有16点阵,24点阵字库等等。不准备过多的介绍汉字点阵字库的构成,这里只谈实现方法。为了在手表上写出汉字,首先要获得所写汉字的字模数据。实现思路如下;

第一步:利用高级语言获得所写汉字的字模数据
第二步:将其转化成MonkeyC的可以存贮的数据
第三步:利用MonkeyC的图形功能,将这些数据代表的汉字画在手表上

下面是笔者用C# 实现的获得汉字字模数据的核心代码,并且将其转化成了MonkeyC的数组形式

public static string Draw(string zkFIle, string hz, int fontSize, PictureBox pbx)
        {
            // Convert the Chinese character to GB2312 encoding
            fontData = File.ReadAllBytes(zkFIle);

            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

            byte[] hzBytes = System.Text.Encoding.GetEncoding("GB2312").GetBytes(hz);
            // Create a new bitmap to render the character
            Bitmap bitmap = new Bitmap(hzBytes.Length / 2 * fontSize, fontSize);
            for (int i = 0; i < hzBytes.Length; i += 2)
            {
                var byteSize = fontSize / 8 * fontSize;
                byte[] bitmapData = new byte[byteSize];
                int offset = ((hzBytes[i] - 0xA1) * 94 + (hzBytes[i + 1] - 0xA1)) * byteSize;
                Array.Copy(fontData, offset, bitmapData, 0, byteSize);
                // Render the character bitmap
                for (int j = 0; j < fontSize; j++)
                {
                    var byteCnt = fontSize / 8;// the byte count for per line 
                    for (int k = 0; k < byteCnt; k++)
                    {
                        for (int l = 0; l < 8; l++)
                        {
                            int dot = (bitmapData[j * byteCnt + k] << l) & 0x80;
                            bitmap.SetPixel(i * fontSize / 2 + l + 8 * k, j, dot == 0 ? Color.White : Color.Black);

                        }
                    }
                }
                // Display the rendered image in the picture box
                pbx.Image = bitmap;
                //MessageBox.Show(String.Format("Press any key to continue,step is {0}",step));


            }
            //Generate monkey C  code to store the bytes data 
            string hexArr = "";
            string oneHZ = "";
            for (int i = 0; i < hzBytes.Length; i += 2)
            {
                // Get the bitmap data for the character
                var byteSize = fontSize / 8 * fontSize;
                byte[] bitmapData = new byte[byteSize];

                int offset = ((hzBytes[i] - 0xA1) * 94 + (hzBytes[i + 1] - 0xA1)) * byteSize;

                byte[] bitHZDat = new byte[byteSize];
                Array.Copy(fontData, offset, bitHZDat, 0, byteSize);
                oneHZ = "";
                for (int j = 0; j < byteSize; j++)
                {
                    oneHZ += string.Format("{0},", bitHZDat[j]);
                }
                oneHZ += oneHZ += string.Format("{0}", bitHZDat[byteSize-1]);

                hexArr += string.Format("[{0}] as Array< Number>,\r\n", oneHZ);
            }
            hexArr = string.Format("//The following data are the matrix for {0}\r\nvar HzBytes = [{1}] as Array< Array<Number> >;", hz, hexArr.Substring(0, hexArr.Length - 1));

            return hexArr;
        }
    }

函数需要输入汉字库的文件、需要处理的汉字,点阵数和图形控件;函数返回以MonkeyC数组形式保存的字模数据。

对应的简单界面如下:

Android 蓝牙手表应用开发 安卓手表app开发_佳明手表APP开发

3.MonkeyC 汉字输出函数

汉字输出函数参考了C#画汉字的方法,核心是使用了移位操作符,用以判断汉字字模数据位的0 和1。 如果为1 就画出一个点,否则就不画。
MonkeyC的函数如下:

public function DrHZ(dc as Dc, x as Number,y as Number,fontSize as Number) as Void {
            //The following data are the matrix for 马拉孙跑世界
            // 这场模拟一个二维数组,其内部的每个子数组对应一个汉字
            var HzBytes = [[0,0,0,0...] as Array< Number>,
            [2,0,0,3,128,0,... as Array< Number>,
            ...,
            ] as Array< Array<Number> >;
        // the cnout of the HZ 
        for (var i = 0; i < HzBytes.size(); i++)
        {
                // Get the bitmap data for the character
    
                // Render the character bitmap
            // from the first line of the matrix of the HZ matrix
            for (var j = 0; j < fontSize; j++)
            {
                
                var byteCnt = fontSize / 8;
                // the byte count of each line 
                for (var bcnt = 0; bcnt < byteCnt; bcnt++){
                    // bit check 
                    for (var k = 0; k < 8; k++)
                    {
                        var dot = HzBytes[i][j*byteCnt+bcnt] ;
                        dot <<=k; 

                        var X = x + bcnt*8+k + i*fontSize;
                        var Y = y+j;
                        if(dot&0x80 !=0){
                            dc.drawPoint(X, Y);
                        }
                      
                    }
                }
            }
        }

    }

如果不了解汉字字模的构成原理,上面的代码是很难看懂的。因此,建议感兴趣的读者,先看看汉字点阵字库的原理和输出介绍。笔者也会后续文章中,从笔者理解的角度给出一个介绍。

上面代码已经经过测试,模拟效果和实际效果如下:

Android 蓝牙手表应用开发 安卓手表app开发_点阵汉字读取和输出_02

Android 蓝牙手表应用开发 安卓手表app开发_MonkeyC 编程_03


Build 和部署

Build

在vscode 中 , shift+ctrl+p 在上面的list 中选择 build 选项,如图

Android 蓝牙手表应用开发 安卓手表app开发_MonkeyC 编程_04


选择生成文件的目录

部署

手表连接电脑, 将生成的.prg 文件拷贝到下面的目录中,如图:

Android 蓝牙手表应用开发 安卓手表app开发_Android 蓝牙手表应用开发_05

总结

通过联合使用电脑上的高级语言以及佳明手表的开发语言,可以对佳明英文版手表进行部分提示的汉化。进而可以大胆的设想一下,是不是可以总体上实现一个汉化的英文版佳明手表呢?如果能实现,这不仅仅是一个有趣的开发,也会有不小的收获呢。为什么呢?因为佳明的中文手表比英文的贵了将近50%!

maraSun 于 河南郑州二七广场附近。
ps:1、笔者将开发一个符合自己特色的佳明表盘和跑步计时部件。