微信小程序在页面上加载图片
图片207.bmp,尺寸100x46
首先定义一个300x300的画布
<canvas style="width: 300px; height: 300px;" canvas-id="firstCanvas">canvas>
JS代码
定义公共变量
var nw = 100;
var nh = 46;
onReady事件加载图片
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为我生成的图片数据
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数组存放了图像数据
以下代码将图像数组转化为打印指令
*用来存储转换后的 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
通过一个自定义函数,将图像数据输出打印
writearray(HCOM1,@imgdata,K)
接来就不需要再通过VFP来测试了,使用小程序操控蓝牙打印机进行打印了。