佳明手表APP开发系列01——简单汉化英文版

news2024/12/24 20:18:55

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

文章目录

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


前言

佳明手表是可以编程的,一直想试一试。由于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数组形式保存的字模数据。

对应的简单界面如下:
在这里插入图片描述

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);
                        }
                      
                    }
                }
            }
        }

    }

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

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

实际效果图


总结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/422325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝海创意云应邀参与苏州市元宇宙生态大会

4月14日&#xff0c;苏州市软件行业协会元宇宙专委会成立大会暨元宇宙生态大会在苏成功举办。此次大会由苏州市工业和信息化局指导&#xff0c;苏州高新区&#xff08;虎丘区&#xff09;经济发展委员会、苏州市软件行业协会主办&#xff0c;蓝海彤翔集团作为协办单位参与此次大…

IDEA集成Git、GitHub、Gitee

一、IDEA 集成 Git 1.1、配置 Git 忽略文件 为什么要忽略他们&#xff1f; 与项目的实际功能无关&#xff0c;不参与服务器上部署运行。把它们忽略掉能够屏蔽 IDE 工具之间的差异。 怎么忽略&#xff1f; 创建忽略规则文件 xxxx.ignore&#xff08;前缀名随便起&#xff0c…

创建Google play开发者账号,并验证身份通过

一、注册前准备 最好准备一台没有怎么用过Google的电脑和&#x1fa9c;准备一个没有注册过Google的手机号准备一张信用卡或者借记卡&#xff08;需要支付$25&#xff09;&#xff0c;支持的类型如下图 这里还需注意&#xff1a;最后账号注册成功还需要验证身份也就是实名认证&…

关于Python爬虫的一些总结

作为一名资深的爬虫工程师来说&#xff0c;把别人公开的一些合法数据通过爬虫手段实现汇总收集是一件很有成就的事情&#xff0c;其实这只是一种技术。 初始爬虫 问题&#xff1a; 什么是爬虫&#xff1f; 网络爬虫是一种按照一定的规则&#xff0c;自动地抓取网络信息的程…

动态规划算法OJ刷题(3)

CC19 分割回文串-ii 问题描述 给出一个字符串s&#xff0c;分割s使得分割出的每一个子串都是回文串。计算将字符串s分割成回文串的最小切割数。例如:给定字符串s“aab”&#xff0c;返回1&#xff0c;因为回文分割结果[“aa”,“b”]是切割一次生成的。 解题思路 方法1&…

计算机操作系统(第四版)第四章存储器管理—课后习题答案

1.为什么要配置层次存储器&#xff1f; &#xff08;1&#xff09;设置多个存储器可以使存储器两端的硬件能并行工作。 &#xff08;2&#xff09;采用多级存储系统,特别是Cache技术,这是一种减轻存储器带宽对系统性能影响的最佳结构方案。 &#xff08;3&#xff09;在微处理机…

《Java8实战》第5章 使用流

上一章已经体验到流让你从外部迭代转向内部迭代。 5.1 筛选 看如何选择流中的元素&#xff1a;用谓词筛选&#xff0c;筛选出各不相同的元素。 5.1.1 用谓词筛选 filter 方法&#xff0c;该操作会接受一个谓词&#xff08;一个返回boolean 的函数&#xff09;作为参数&am…

MySQL数据库:聚合函数、分组查询、约束、默认值设置、自增属性

一、聚合函数 1.聚合函数 在MySQL数据库中预定义好的一些数据统计函数。 2.count(*) 功能&#xff1a;统计结果条数。 3.sum(字段名) 功能&#xff1a;对指定字段的数据求和。 4.avg(字段名) 功能&#xff1a;对指定字段的数据求平均值。 5.max(字段名) 和 min(字段名) …

正则化的基本认识

正则化(一) 拟合与欠拟合(二) 正则化的目的(三) 惩罚项&#xff08;3.1&#xff09;常用的惩罚项&#xff1a;&#xff08;3.2&#xff09;L-P范数&#xff1a;&#xff08;3.3&#xff09;L1与L2的选择&#xff1a;(一) 拟合与欠拟合 欠拟合&#xff1a; 是指测试级与训练集都…

docker目录映射

docker 常用命令 docker ps // 查看所有正在运行容器 docker stop containerId // containerId 是容器的ID docker ps -a // 查看所有容器 $ docker ps -a -q // 查看所有容器ID docker stop $(docker ps -a -q) // stop停止所有容器 docker rm $(docker ps -a -q) // remove删…

受害者有罪论——如何反驳

目录 一、那些「受害者有罪论」的说法 二、「受害者有罪论」的潜台词 三、如何反驳 反驳1&#xff1a;让受害者有罪论者感同身受 反驳2&#xff1a;说理 反驳3&#xff1a; 直接指出结论的错误 反驳4&#xff1a;与对方无关&#xff0c;不用多费唇舌 四、罪犯就是罪犯&…

golang-gin框架入门

基础 快速入门 gin完整支持路由框架支持全局异常&#xff08;错误&#xff09;处理内置渲染高可扩展 组件 在gin框架中四个基本组件是&#xff1a; Engine&#xff1a;是web server的根数据结构&#xff0c;也是基础容器&#xff1b;它包含复用器、中间件和配置设置。类似S…

GC 垃圾回收算法、垃圾回收器及 JVM 调优【JVM知识点-resu】

JVM知识点 详情请见&#xff1a;垃圾回收算法、垃圾收集器详情请见&#xff1a;JVM调优 1 GC垃圾回收算法 众所周知&#xff0c;Java的内存管理是交由了JVM&#xff0c;那么程序时时刻刻都在产生新对象&#xff0c;为了避免内存溢出&#xff0c;此时必然会涉及到垃圾回收&…

【MySQL数据库原理】Python3.7 中连接 MySQL 数据库

目录 1、安装mysql-connector-python2、连接 MySQL 数据库3、修改数据库1、安装mysql-connector-python 要在 Python 中连接 MySQL 数据库 “test”,可以使用 “mysql-connector-python” 包。首先,确保已经安装了该包。可以使用 pip 命令进行安装: pip install mysql-con…

[abc复盘] abc297 20230409

[atc复盘] abc297 20230409 一、本周周赛总结A - Double Click1. 题目描述2. 思路分析3. 代码实现B - chess9601. 题目描述2. 思路分析3. 代码实现C - PC on the Table1. 题目描述2. 思路分析3. 代码实现D - Count Subtractions1. 题目描述2. 思路分析3. 代码实现E - Kth Takoy…

Spring 04 -SpringAOP开发

SpringAOP开发SpringAOP1 原理2 动态代理2.1 JDK动态代理2.2.2 Cglib动态代理2.2.3 **JDK动态代理和Cglib动态代理**3 SpringAOP3.1 AOP专业术语3.2 环境搭建3.3 基于XML配置3.4 基于注解配置2.5 通知类型面向切面编程&#xff0c;在不修改源代码的情况加&#xff0c;对类功能实…

人工智能中的顶级会议

当搭建好了AI领域的知识架构&#xff0c;即具备了较好的数学、编程及专业领域知识后&#xff0c;如果想在AI领域追踪前沿研究&#xff0c;就不能再只看教材了。毕竟AI领域的发展一日千里&#xff0c;教材上的知识肯定不是最新的。此时&#xff0c;应该将关注的重点转向AI领域的…

JavaWeb - Web网站的组成,工作流程以及开发模式

一. Web Web&#xff1a;全球广域网&#xff0c;也称玩万维网(www Wrold Wide Web)&#xff0c;就是能够通过浏览器访问的网站学习Web开发&#xff0c;其实就是要使用Java这门语言来开发这样的Web网站&#xff0c;这也是现在Java语言最主流的企业级应用方式。使用Java语言开发…

Nginx基本配置 Nginx服务基础Nginx访问控制Nginx虚拟主机

本章结构 Nginx服务基础 Nginx访问控制 Nginx虚拟主机 原理&#xff1a; 关于Nginx 一款高性能、轻量级Web服务软件 稳定性高 系统资源消耗低 apache多线程或多进程实现连接&#xff08;多线程比多线程稍微好些&#xff0c;切换资源浪费少&#xff09; Nginx单线程 对HTTP并发…

自己动手写CPU——第二篇

1 ori指令说明 ori是进行逻辑 或 运算的指令&#xff0c;其指令格式如下所示 从以上的指令格式&#xff0c;我们可以直到&#xff0c;这是一个I类型指令&#xff0c;ori指令的指令码是 6‘b001101&#xff0c;所以当处理器发现正在处理的指令的高6bit 是 001101 的时候&#x…