Android硬件控制之POS热敏打印(支持任意图表)

本文介绍了在Android上实现Pos热敏打印的场景、难点及解决办法,特别是如何让只支持黑白的打印机打印出灰阶效果。通过连接设备、设置打印图片、生成打印内容及打印图片的步骤,详细解析了打印过程,包括图片缩放、去色、抖动算法等关键环节。最后,讨论了打印过程中可能遇到的问题及解决方案。
摘要由CSDN通过智能技术生成

简介

在Android实现Pos打印的应用场景?实现pos打印的难度?如何用只支持黑白的热敏打印机打印出灰阶效果?

在Android实现Pos打印的应用场景?

pos热敏打印机在平时生活中还是挺常见的,一般在超市、饭店看到打印小票的就是热敏打印机了。其实现在很多的收银设备、扫描支付设备都是在Android板上开发的。只是外接的一个pos热敏打印机。可以想象这样功能单一的程序开发难度。当然Pos热敏打印机还能用在银行等排队系统中,用于打印凭条时使用。Pos热敏打印的应用场景还是挺多的,它的优势在于打印方便、价格便宜(有的不到一百大洋)、连接简单。

实现pos打印的难度?

要实现Pos打印主要难度集中在两部分:1、如何连接Pos打印机,实现通讯。2、如何打印出想要格式的内容。对于连接Pos打印,这个目前主要有三种连接方式:蓝牙、USB、socket。蓝牙我目前还没有试过(感觉应该也不难),不过后两种连接方式我都尝试过,根据固定步骤开启通讯通道即可(参见:Android硬件控制之USB连接)。如何打印出想要的内容?通常对于打印来说,打印简单的文字、符号是比较简单的,如果打印图表就会比较难,而且普通买的Pos打印机,几乎都没有什么打印开发SDK什么的,所有要实现复杂的打印普遍都是自己去研究pos的打印指令(我是不愿意去研究),而我对与复杂的pos打印都是通过先生成图片、然后打印的方式实现,大大降低了打印难度,简单易懂。

如何用只支持黑白的热敏打印机打印出灰阶效果?

很多人初次接触Pos热敏打印机打印一张彩色图片时,当看到一张黑白图片打印出来后和原图完全不同,都会怀疑是不是这个打印机不支持?是不是这种Pos打印机不适合打印图片?这点完全不用怀疑。打印的图片没有灰阶效果是因为你没有在图片中加上抖动效果(这个曾经困扰我很久的一个问题)。

效果图

实现步骤

1.连接设备

这里连接设备包含了物理上的连接(网络、蓝牙、usb等),物理连接成功后,根据你使用的不同通讯方式,实现基础的于设备间通讯。(这里我就不详细介绍了)。

2.打印图片设置

在百度上现在大量的关于POS打印采用PrinterUtils这样的方式,通过特殊的指令实现打印效果,虽然有人已经经过大量的封装了,但是使用时还是要对基本指令有所了解,例如:

 /**
     * 对齐方式
     *
     * @param alignMode
     * @return
     */
    public static String getAlignCmd(int alignMode) {
        byte[] data = {(byte) 0x1b, (byte) 0x61, (byte) 0x0};
        if (alignMode == ALIGN_LEFT) {
            data[2] = (byte) 0x00;
        } else if (alignMode == ALIGN_CENTER) {
            data[2] = (byte) 0x01;
        } else if (alignMode == ALIGN_RIGHT) {
            data[2] = (byte) 0x02;
        }

        return new String(data);
    }

仅仅是一个文字的对齐方式,在每次需要使用这种对齐方式的时候,都需要先设置以下,才会生效。而且这种pos编码有的时候会存在不用打印机尺寸上打印的效果有所差异。所以我这里采用的是先根据内容生成图片、然后打印的方式。对于图片打印只需要关注以下几步即可:

a.图片缩放。因为打印纸是固定宽度的,所以必须将图片缩放到打印纸的最大宽度,否则超出后容易出现乱码.

 public static Bitmap zoomDrawable(Bitmap oldbmp, int w, int h) {
        int width = oldbmp.getWidth();
        int height = oldbmp.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidth = ((float) w / width);
        float scaleHeight = ((float) h / height);
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height,
                matrix, true);
        return newbmp;
    }

b.图片去色。由于热敏打印机是支持黑白色打印的,所以最好将彩图转化为灰阶图片。

 private static Bitmap toGrayScale(Bitmap bmpOriginal) {
        int width, height;
        height = bmpOriginal.getHeight();
        width = bmpOriginal.getWidth();

        Bitmap bmpGrayScale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        Canvas c = new Canvas(bmpGrayScale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        c.drawBitmap(bmpOriginal, 0, 0, paint);
        return bmpGrayScale;
    }

c.图片抖动算法。图片抖动的作用是根据灰度的不同产生不同密度的黑色像素,在用单色时达到灰阶的算法。(至于这个算法的具体是怎么设计的,这个我也没有深入研究)

 public static Bitmap convertGreyImgByFloyd(Bitmap img) {
        int width = img.getWidth();         //获取位图的宽
        int height = img.getHeight();       //获取位图的高
        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组
        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int[] gray = new int[height * width];
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                int red = ((grey & 0x00FF0000) >> 16);
                gray[width * i + j] = red;
            }
        }
        int e = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int g = gray[width * i + j];
                if (g >= 128) {
                    pixels[width * i + j] = 0xffffffff;
                    e = g - 255;
                } else {
                    pixels[width * i + j] = 0xff000000;
                    e = g;
                }
                if (j < width - 1 && i < height - 1) {
                    //右边像素处理
                    gray[width * i + j + 1] += 3 * e / 8;
                    //下
                    gray[width * (i + 1) + j] += 3 * e / 8;
                    //右下
                    gray[width * (i + 1) + j + 1] += e / 4;
                } else if (j == width - 1 && i < height - 1) {//靠右或靠下边的像素的情况
                    //下方像素处理
                    gray[width * (i + 1) + j] += 3 * e / 8;
                } else if (j < width - 1 && i == height - 1) {
                    //右边像素处理
                    gray[width * (i) + j + 1] += e / 4;
                }
            }
        }
        Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return mBitmap;
    }

d.将转化后的图片数据转化为打印字节数据。

  /*************************************************************************
     * 我们的热敏打印机是RP-POS80S或RP-POS80P或RP-POS80CS
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值