欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

Android 打印之将文字转换成 Bitmap 图片,再转换成Bytes 数组 进行打印

程序员文章站 2022-03-21 18:40:26
Android 打印之将文字转换成 Bitmap 图片,再转换成Bytes 数组 进行打印一、前言Android 打印解决文字显示?问好 乱码最近在处理打印的时候,打印机有些繁体的字无法打印出来,或者其它韩文打印出来显示 ? 问题解决思路:将需要打印的 String 文本内容,先转换成 Bitmap 位图 , 然后将图片转换成打印机能打印的byte[]类型不同印机 最终丢给印机打印的方法不同。如下图,打印的是一栏地址,原来第三个字呢打印出来是 ? 号的 ,这张图是用以下的转换方法修复...

Android 打印之将文字转换成 Bitmap 图片,再转换成Bytes 数组 进行打印

一、前言

Android 打印解决文字显示?问好 乱码

最近在处理打印的时候,打印机有些繁体的字无法打印出来,或者其它韩文打印出来显示 ? 问题

解决思路:

将需要打印的 String 文本内容,先转换成 Bitmap 位图 , 然后将图片转换成打印机能打印的byte[]类型

不同印机 最终丢给印机打印的方法不同。

如下图,打印的是一栏地址,原来第三个字呢打印出来是 ? 号的 ,这张图是用以下的转换方法修复后的。

使用印机都是 EPSON,其它也类似。

左边的是 网络打印 (通过 OutputStream 流的方式 将 byte[] 写入 到缓冲区)

右边的是 USB 连接 EPSON 打印 (通过EPSON SDK的方法,addImage() ) 打印出来的很OK

其实还有一个问题就是,通过网络传递的Esc 指令打印之后,打印文字可能打印像素有点不全的问题 ,我感觉是 下面的 genBitmapCode 方法 转换出来的时候,像素精度还是什么问题 ,如果有好的解决方式 请给我留言 谢谢。

Android 打印之将文字转换成 Bitmap 图片,再转换成Bytes 数组 进行打印

下面提供了 ,创建Bitmap 图片, 创建 QRCode 二维码图片 ,转换成 Bytes 数组 进行打印

二、将文字转换成Bitmap

    /**
     * 根据文字创建一个 bitmap  , 打印的位图需要 黑字 白底
     *
     * @param text
     * @param height
     * @param width
     * @return
     */
    public Bitmap getNewBitMap(String text, int height, int width) {
        Bitmap newBitmap = createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(newBitmap);
        canvas.drawColor(Color.WHITE);

        canvas.drawBitmap(newBitmap, 0, 0, null);
        TextPaint textPaint = new TextPaint();
        textPaint.setAntiAlias(true);
        textPaint.setTextSize(height * 2 / 3);
//        textPaint.setColor(Color.rgb(0, 0, 0));
        textPaint.setColor(Color.BLACK);
        //     "在Android开发中,Canvas.drawText不会换行,即使一个很长的字符串也只会显示一行,超出部分会隐藏在屏幕之外.StaticLayout是android中处理文字的一个工具类,StaticLayout 处理了文字换行的问题";
        StaticLayout sl = new StaticLayout(text, textPaint, newBitmap.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
        textPaint.setStyle(Paint.Style.FILL);
        canvas.translate(0, height / 10);
        sl.draw(canvas);
        return newBitmap;
    }


    /**
     * 生成二维码bitmap 要转换的地址或字符串,可以是中文
     *
     * @param url
     * @param width
     * @param height
     * @return
     */
    public Bitmap createQRImage(String url, final int width, final int height) {
        try {
            // 判断URL合法性
            if (url == null || "".equals(url) || url.length() < 1) {
                return null;
            }
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // 图像数据转换,使用了矩阵转换
            BitMatrix bitMatrix = new QRCodeWriter().encode(url,
                    BarcodeFormat.QR_CODE, width, height, hints);
            int[] pixels = new int[width * height];
            // 下面这里按照二维码的算法,逐个生成二维码的图片,
            // 两个for循环是图片横列扫描的结果
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * width + x] = 0xff000000;
                    } else {
                        pixels[y * width + x] = 0xffffffff;
                    }
                }
            }
            // 生成二维码图片的格式,使用ARGB_8888
            Bitmap bitmap = createBitmap(width, height,
                    Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
            return bitmap;
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return null;
    }




三、把图片转换成POS机能打印的byte[]类型

  /**
     * 将图片转换成POS机能打印的byte[]类型
     *
     * @param bm
     * @param doubleWidth
     * @param doubleHeight
     * @return
     */
    private static byte[] genBitmapCode(Bitmap bm, boolean doubleWidth, boolean doubleHeight) {
        int w = bm.getWidth();
        int h = bm.getHeight();
//        if(w > MAX_BIT_WIDTH)
//            w = MAX_BIT_WIDTH;
        int bitw = ((w + 7) / 8) * 8;
        int bith = h;
        int pitch = bitw / 8;
        byte[] cmd = {0x1D, 0x76, 0x30, 0x00, (byte) (pitch & 0xff), (byte) ((pitch >> 8) & 0xff), (byte) (bith & 0xff), (byte) ((bith >> 8) & 0xff)};
        byte[] bits = new byte[bith * pitch];
        // 倍宽
        if (doubleWidth) {
            cmd[3] |= 0x01;
        }
        // 倍高
        if (doubleHeight) {
            cmd[3] |= 0x02;
        }
        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                int color = bm.getPixel(x, y);
                if ((color & 0xFF) < 128) {
                    bits[y * pitch + x / 8] |= (0x80 >> (x % 8));
                }
            }
        }

        ByteBuffer bb = ByteBuffer.allocate(cmd.length + bits.length);
        bb.put(cmd);
        bb.put(bits);

        return bb.array();
    }

四、调用打印文本方式

      //生成的bitmap 显示 固定是一行 ,如果要生成多行,需要自行通过文本控制Bitmap的宽高
                Bitmap newBitMap = getNewBitMap(IMAGE, 20, 300);

                byte[] bytes = genBitmapCode(newBitMap, true, true);
                 
							//此方式是网络打印 通过 OutputStream 流的方式 将 byte[] 写入 到缓冲区
                socketOut.write(bytes);
							

五、EPSON 爱普生 中打印图片的方式

	       //创建单行文字 
 					Bitmap newBitMap = getNewBitMap(IMAGE, 40, 600);

            //打印图片 方式 1  打印出来很漂亮
            mPrinter.addImage(newBitMap, 0, 0,
                    newBitMap.getWidth(),
                    newBitMap.getHeight(),
                    Printer.COLOR_1,
                    Printer.MODE_MONO,
                    Printer.HALFTONE_DITHER,
                    Printer.PARAM_DEFAULT,
                    Printer.COMPRESS_AUTO);
		
		// 方式2 打印出来 有少像素没打全
		  Bitmap newBitMap = getNewBitMap(IMAGE, 20, 300);

            byte[] bytes = genBitmapCode(newBitMap, true, true);
                 
			mPrinter.addCommand(bytes)

六、调用打印二维码图片


		          Bitmap qrImage = createQRImage("qr123456", 170, 170);

                byte[] bytes = genBitmapCode(qrImage, true, true);

                socketOut.write(bytes);

以上代码只是作为一个参考思路, 主要是 将 String 转换 为 Bitmap ,再丢给打印机 进行打印。

不同印机应优选考虑不同的调用方式,如果是 USB 连接 EPSON 的话 其实也支持 Esc 指令 进行命令打印的。

网络打印的话,只能传递 Esc 指令集 通过流的方式传输进行打印了。

本文地址:https://blog.csdn.net/a23006239/article/details/107868456