【小程序码 - 设计篇】菊花绽放

作者:lincolnlin,endyxu,changoran

2017 年四月,微信正式推出了小程序码。小程序码的使命及诞生的过程, 扫码背后藏了什么秘密?小程序码又为何长得像菊花? | 你问鹅答一文已经作过一番介绍。本文将为你剖析更多关于小程序码的技术细节。

小程序码的前世

初见小程序码,犹如一朵盛开的菊花。

其实这种脑洞大开的异形码并非微信首创,Facebook、kik、snapchat 等公司都研发了自己体系的码。

从设计的图形上,我们把上述方案简单分成:

? 平面类 如 qrcode ,snapchart code

? 环状类 如 fb code,kik code,

考虑到专利风险,又要兼顾优雅美观,我们最终选择放射状作为我们的 base 方案,也就是最后面世的“菊花码”。

小程序码的构成

小程序的 3 个“牛眼”用来定位,放射线条编码信息,这是一个大家都懂的原理。但”麻雀虽小,五脏俱全“,小程序码与 QRCode 类似,同样包含了定位区,编码信息区,元信息区等部分,除此以外,我们还加入了自定义 Logo 区,下面让我们来解剖一下小程序码。

如何生成一个小程序码

”万丈高楼平地起“,那小程序码是如何一砖一瓦构建起来的呢?我们以一个实例来演示小程序码的生成 。

1 .定位点

定位点主要用于标记小程序码的大小及在图中的位置,与 QRCode 类似,我们采用了 3+1 的方案,3 个主定位点加一个辅助定位点。可以发现,定位点的对角连线交点刚好是码的圆心,3 个主定位点又刚好组成一个等腰直角三角形。以上的特征,非常有利于定位识别。

2 .信息编码区

我们会把原始编码的字符串,转换成 01 的序列,再加入纠错码,得到最终 01 序列。我们只需要把 01 序列按一定的编码路径,填充到信息编码区的方格中即可(0 为白,1 为黑)。小程序在图案编码阶段,也是按点编码的的,并没有线的概念。

3 .掩码图案

填充好编码区之后,我们发现图案与设计稿大相径庭,并没有发射状线条的感觉。究其原因,是因为黑色点过于稀疏。所以我们还要做 mask,加上掩码图案。

mask 的原理其实就是拿一个掩码图案与原图做 XOR 操作,在解码阶段,再做一次 XOR 操作,两次 XOR 操作,我们得到了原始的数据区。

我们按照一定的规则,预先设定了 32 种 mask 模板。在码生成阶段,会寻找一个最佳的 mask,让我们的黑白分布更具线条感。mask 完成后,我们得到了下面的效果图。

4 .元信息区

前面我们提到,小程序码分为多个版本,每个版本有 4 个纠错 Level,同时 mask 阶段又有一个独特的 mask id。这些信息,我们称之为元信息,需要独立编码到图案中,并且本身具备纠错能力。

至此,我们已经把所有必不可少的信息写入到图案中,码本身已经是可识别的了。为了让整体更加美观,需要对内外圈再进行一些处理。

5 .轮廓填充区

为了凸显 logo 的形状,我们在内圈留了一些区域作为轮廓填充区。

6 .边缘补全区

最外圈也不带有编码信息,用于勾勒图案的轮廓,总体上我们有以下两种方案

方案一更突出图案更加圆的特点,但方案二可以让线条显得更加错落有致,也是我们的最终选择。

可扩展

  • 为了让小程序码在编码容量上的需求,我们设计了 36 线,54 线,72 线三种版本,每个版本支持由低到高 L,M,Q,H 四种纠错等级,分别能纠错 10%,15%,25%,35%的信息。

  • 不同的版本,在不同的纠错 Level 下,采用不同的字符集,其最大编码容量如下

编后语

从小程序码设计上,有以下几个特点

  • 高识别度 保留最核心的中间区域给使用者自定义,让每个品牌商都有自己的专属码
  • 高容错 实际应用中,大部分 QRCode 由于中间部分被 logo 覆盖,有效编码区域丢失。而小程序码是无损的,在相同纠错等级的情况下,容错性更高。
  • 更安全 QRCode 由于其开放性,容易成为“病毒”的温床。而小程序码采用完全私有的协议,只有微信可以生成,也只有微信可以解码,用户可以放心的打开扫一扫。

最后我们再通过下图,感受一下小程序码这朵“菊花”绽放的过程。

此文已由作者授权腾讯云技术社区发布,转载请注明文章出处

时间: 2024-08-19 01:27:04

【小程序码 - 设计篇】菊花绽放的相关文章

C# 生成小程序码

1 /// <summary> 2 /// B接口-微信小程序带参数二维码的生成 3 /// </summary> 4 /// <param name="access_token"></param> 5 /// <returns></returns> 6 public static string CreateWxCode(string access_token string roomId) 7 { 8 string

小程序-将页面生成一个小程序码分享出去

这个需求我遇到过2次.一次是在识别二维码后跳转到其它页面,另一次是识别二维码后进入到生成小程序码的当前页面. 我有一个梦想,就是成为一名黑客!!!!!! 小程序中js wx.request({        url: '',        method: 'POST',        data: {        ModuleName: "",    //空间名 接口文档里每个接口会有标明 必填        MethodName: "GetQrCode",   

后台生成带参跳到指定页面的小程序码

方法步骤如下: 1. 获取 access_token 详见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183 2. 生成小程序码 接口B:适用于需要的码数量极多的业务场景 0)可接受页面参数较短 1)通过该接口生成的小程序码,永久有效 2)数量不做限制(截止今天,官方未对生成数量做限制) 3)用户扫码后,可以在对应页面获取到二维码中scene字段下面的值 4)B接口调用分钟频率受限(目前5000次/分钟,会调整)

PHP获取小程序码并返回前端显示图片

小程序的二维码分为小程序码和二维码: 生成小程序二维码文档中说后端来生成. 参考 小程序开发文档资料:https://developers.weixin.qq.com/miniprogram/dev/api/getWXACodeUnlimit.html 文档的参数介绍还是蛮详细的,但是没有具体的demo,对于请求的接口的返回值是进制流(也就是在浏览器显示一堆乱码)也是很令人懊恼,这里贴一下我的代码: //获取小程序码,这里调用的是小程序码的A接口类型 public function getQRC

php实现小程序码自定义中间icon

小程序码生成的时候是默认使用小程序后台设置的小程序icon图片的,但是在有些场景我们可能要替换成我们自己想要的icon. 下面先放代码: public function makeNewQrCodeAction() { //获取用户头像并转string $avatarUrl = $this->_req->getQuery('avatarUrl', ""); if (!$avatarUrl) { response::err_lack_param(); } $avatar_fil

生成微信小程序码java实现

@Override public ModelAndView onSubmit(HttpServletRequest req, HttpServletResponse res, WxQrCodeForm cmd, BindException err) throws Exception { SimpleResult<Object> result = SimpleResult.create(false); Locale locale = new Locale("en", &quo

生成指定页面带参数的小程序码及踩坑

//获取accessToken let that = this; const APP_ID = 'yourapp_id';// 小程序appid const APP_SECRET = 'yourapp_secreat';// 小程序app_secret let access_token = ''; wx.request({ url:"https://api.weixin.qq.com/cgi-bin/token", data: { grant_type: 'client_credent

关于.NET HttpClient方式获取微信小程序码(二维码)

随着微信小程序的火热应用,市面上有关小程序开发的需求也多了起来.近来分析了一项生成有关生成微信小程序码的需求——要求扫码跳转到小程序指定页面(带参数):看了下小程序官方文档,以及网上的例子,未看到多少有价值的采用C#调用小程序接口生成小程序码的例子,于是拾起多年前的代码,略作分析尝试,在此分享给有需要的人,并以此抛砖引玉. 此文以HttpClient方式示例,当然采用老旧的HttpWebRequest也可以,在此不作分析.生成微信小程序码(二维码)的接口主要有三个: https://develo

小程序生成小程序码

getUnlimited 获取小程序码,适用于需要的码数量极多的业务场景.通过该接口生成的小程序码,永久有效,数量暂无限制. 小程序官方文档 wxacode.getUnlimited /// <summary> /// 获取小店小程序码 /// </summary> /// <returns>返回的图片 Buffer</returns> public object GetWxacode(string pagePath, int width, string I