前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序操作蓝牙打印机3-图片处理原理

微信小程序操作蓝牙打印机3-图片处理原理

作者头像
加菲猫的VFP
发布2021-08-16 14:48:26
1.4K0
发布2021-08-16 14:48:26
举报
文章被收录于专栏:加菲猫的VFP

微信小程序在页面上加载图片

图片207.bmp,尺寸100x46

首先定义一个300x300的画布

代码语言:javascript
复制
<canvas style="width: 300px; height: 300px;" canvas-id="firstCanvas"></canvas>

JS代码

定义公共变量

var nw = 100;

var nh = 46;

onReady事件加载图片

代码语言:javascript
复制
var ctx = wx.createCanvasContext('firstCanvas')        
ctx.drawImage('../../images/207.bmp', 0, 0, nw, nh)
ctx.draw(true, () => {
})

效果如下图

微信小程序有个API

wx.canvasGetImageData 可以获取图像数据

图像数据其实是一个一维的数组,数组的大小是图像的长x宽x4计算得到的.

我们知道图像是由一个个像素组成的,一个彩色的点由RGB三色组成的。在微信小程序中再加一个alpha

值,也就是透明值。也就是说,每四点代表一个值。

我们的蓝牙打印只支持黑白二点打印,所以就可以四个值化成一个值

Red Green Blue的取值范围均是0~255

R+B+G之和除以3大于127为白,小于127为黑

代码如下: mytext为我生成的图片数据

代码语言:javascript
复制
getimgdata:function(){
 var that=this;
    wx.canvasGetImageData({
      canvasId: 'firstCanvas',
      x: 0,
      y: 0,
      width: nw,
      height: nh,
      success(res) {
        console.log(res.width)
        console.log(res.height)
        console.log(res.data instanceof Uint8ClampedArray) // true
        console.log(res.data.length)
 var imgData = res;
 var data = new Uint8ClampedArray(res.data.length);
 var prtdata=[]; 
 var mytext="";
 for (var i = 0; i < imgData.data.length; i += 4) {      
 var red = imgData.data[i];
 var green = imgData.data[i + 1];
 var blue = imgData.data[i + 1];
 var alpha = imgData.data[i + 3];    
 var point = 0;
 //彩色直接二值化
 var index=127;
 var sum = (red+green+blue)/3
 if (sum > index) {          
            point = 0;
          } else {           
            point=1;
          }         
          prtdata.push(point);
          mytext += ","+point;    
 // console.log(red + " " + green + " " + blue + " " + alpha);
        }
        that.setData({ myval: mytext });
        console.log(data);
        console.log(prtdata);           
      }     
    })
  }
})

可以看到我的图像数据大小只有原来的四分之一了

这是100x46的图片数据示意图

0代表该像素不打印,1代表是打印

生成的图像数据以逗号分隔组成一段字符串,复制到VFP中

再回回顾一下,我们图像打印指令是按列打印的,列的长度是24个点,也就是说,打印时

第一条指令 1 101 201 301… 2401

第二条指令 2 102 202 302… 2402

以此类推

Larray数组存放了图像数据

以下代码将图像数组转化为打印指令

代码语言:javascript
复制
*用来存储转换后的 bitmap 数据。为什么要再加1000,这是为了应对当图片高度无法
*整除24时的情况。比如bitmap 分辨率为 240 * 250,占用 7500 byte,
*但是实际上要存储11行数据,每一行需要 24 * 240 / 8 =720byte 的空间。再加上一些指令存储的开销,
*所以多申请 1000byte 的空间是稳妥的,不然运行时会抛出数组访问越界的异常。
bmpWidth =100
bmpHeight=46
nsize =bmpWidth * bmpHeight / 8 + 1000
?"图片数组大小",nsize
Dimension imgdata[Nsize]
*设置行距为0的指令
imgdata[1] = 0x1B
imgdata[2] = 0x33
imgdata[3] = 0x00
k = 4
kall=1
*逐行打印
For j = 1 To CEILING(bmpHeight / 24)
    *打印图片的指令
    imgdata[k] = 0x1B
    k=k+1
    imgdata[k] = 0x2A
    k=k+1
    imgdata[k] = 33
    k=k+1
    imgdata[k] =bmpWidth%256 &&nL
    k=k+1
    imgdata[k] =bmpWidth/256 &&nH
    k=k+1
    *对于每一行,逐列打印
    For i = 1 To bmpWidth
        *每一列24个像素点,分为3个字节存储
        For m = 1 To 3
            *每个字节表示8个像素点,0表示白色,1表示黑色
            bitval=0
            nval=0
            For N = 1 To 8
                nxb=(j-1)*24*bmpWidth+(m-1)*8*bmpWidth+(n-1)*bmpWidth+i
                IF nxb<=ALEN(larryx)           
                 nval = nval + VAL(larryx[nxb])*2^(7-n+1) 
                ELSE
                 nval =nval + 0*2^(7-n+1) 
                ENDIF
            ENDFOR
            imgdata[k]=nval
            k = k + 1
        Endfor
    Endfor
    kall = (j-1) * bmpWidth
    imgdata[k] = 10 &&换行
    k=k+1
Endfor && data

通过一个自定义函数,将图像数据输出打印

代码语言:javascript
复制
writearray(HCOM1,@imgdata,K)

接来就不需要再通过VFP来测试了,使用小程序操控蓝牙打印机进行打印了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 加菲猫的VFP 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档