java - 如何在 Android 的蓝牙打印机上打印图像?

标签 java android bitmap bytearray bitmapfactory

我必须在热敏蓝牙打印机上打印一些数据,我正在这样做:

String message="abcdef any message 12345";
byte[] send;
send = message.getBytes();
mService.write(send);

它适用于文本,但不适用于图像。我想我需要获取图像数据的 byte[] 。我尝试以这种方式获取图像的数据:

Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.qrcode);
ByteArrayOutputStream stream=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] image=stream.toByteArray();

很遗憾,打印机打印了很多奇怪的字符(大约 50 厘米的纸)。我不知道如何打印图像。

我想尝试获取位图的像素,然后将其转换为 byte[] 并发送,但我不知道该怎么做。

谢谢

更新:

经过这么长时间,我正在这样做:我有一个名为 print_image(String file) 的方法,它获取我要打印的图像的路径:

private void print_image(String file) {
    File fl = new File(file);
    if (fl.exists()) {
        Bitmap bmp = BitmapFactory.decodeFile(file);
        convertBitmap(bmp);
        mService.write(PrinterCommands.SET_LINE_SPACING_24);

        int offset = 0;
        while (offset < bmp.getHeight()) {
            mService.write(PrinterCommands.SELECT_BIT_IMAGE_MODE);
            for (int x = 0; x < bmp.getWidth(); ++x) {

                for (int k = 0; k < 3; ++k) {

                    byte slice = 0;
                    for (int b = 0; b < 8; ++b) {
                        int y = (((offset / 8) + k) * 8) + b;
                        int i = (y * bmp.getWidth()) + x;
                        boolean v = false;
                        if (i < dots.length()) {
                            v = dots.get(i);
                        }
                        slice |= (byte) ((v ? 1 : 0) << (7 - b));
                    }
                    mService.write(slice);
                }
            }
            offset += 24;
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);          
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
        }
        mService.write(PrinterCommands.SET_LINE_SPACING_30);


    } else {
        Toast.makeText(this, "file doesn't exists", Toast.LENGTH_SHORT)
                .show();
    }
}

我是根据这个 post 做的

这是 PrinterCommands 类:

public class PrinterCommands {
public static final byte[] INIT = {27, 64};
public static byte[] FEED_LINE = {10};

public static byte[] SELECT_FONT_A = {27, 33, 0};

public static byte[] SET_BAR_CODE_HEIGHT = {29, 104, 100};
public static byte[] PRINT_BAR_CODE_1 = {29, 107, 2};
public static byte[] SEND_NULL_BYTE = {0x00};

public static byte[] SELECT_PRINT_SHEET = {0x1B, 0x63, 0x30, 0x02};
public static byte[] FEED_PAPER_AND_CUT = {0x1D, 0x56, 66, 0x00};

public static byte[] SELECT_CYRILLIC_CHARACTER_CODE_TABLE = {0x1B, 0x74, 0x11};

public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 33, -128, 0};
public static byte[] SET_LINE_SPACING_24 = {0x1B, 0x33, 24};
public static byte[] SET_LINE_SPACING_30 = {0x1B, 0x33, 30};

public static byte[] TRANSMIT_DLE_PRINTER_STATUS = {0x10, 0x04, 0x01};
public static byte[] TRANSMIT_DLE_OFFLINE_PRINTER_STATUS = {0x10, 0x04, 0x02};
public static byte[] TRANSMIT_DLE_ERROR_STATUS = {0x10, 0x04, 0x03};
public static byte[] TRANSMIT_DLE_ROLL_PAPER_SENSOR_STATUS = {0x10, 0x04, 0x04};
}

正如在 print_image 方法中看到的,我正在调用一个名为 convertBitmap 的方法,并且我正在发送一个位图,代码如下:

   public String convertBitmap(Bitmap inputBitmap) {

    mWidth = inputBitmap.getWidth();
    mHeight = inputBitmap.getHeight();

    convertArgbToGrayscale(inputBitmap, mWidth, mHeight);
    mStatus = "ok";
    return mStatus;

}

private void convertArgbToGrayscale(Bitmap bmpOriginal, int width,
        int height) {
    int pixel;
    int k = 0;
    int B = 0, G = 0, R = 0;
    dots = new BitSet();
    try {

        for (int x = 0; x < height; x++) {
            for (int y = 0; y < width; y++) {
                // get one pixel color
                pixel = bmpOriginal.getPixel(y, x);

                // retrieve color of all channels
                R = Color.red(pixel);
                G = Color.green(pixel);
                B = Color.blue(pixel);
                // take conversion up to one single value by calculating
                // pixel intensity.
                R = G = B = (int) (0.299 * R + 0.587 * G + 0.114 * B);
                // set bit into bitset, by calculating the pixel's luma
                if (R < 55) {                       
                    dots.set(k);//this is the bitset that i'm printing
                }
                k++;

            }


        }


    } catch (Exception e) {
        // TODO: handle exception
        Log.e(TAG, e.toString());
    }
}

这是 printer我正在使用,分辨率:8 点/毫米,576 点/线

这就是我喜欢做的事情(我使用同一台打印机,但使用从 Play 商店下载的应用程序) Image that I want to print

这就是我现在得到的 My printing trying

更接近: A closer part

更接近2: enter image description here

可以看到一小部分图像,所以我认为我更接近可以打印图像......

我使用的图像是这个 (576x95):enter image description here

这是转换后的图像(我用上面的代码转换它): converted image

Inverted

所以,答案是:我做错了什么?,我认为错误在这个命令中:

  public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 33, -128, 0};

但是,我怎样才能为我的图像计算正确的值?,谢谢

最佳答案

我解决了将位图转换为字节数组的问题。请记住,您的图片必须是黑白格式。

完整源代码: https://github.com/imrankst1221/Thermal-Printer-in-Android

enter image description here

 public void printPhoto() {
        try {
            Bitmap bmp = BitmapFactory.decodeResource(getResources(),
                    R.drawable.img);
            if(bmp!=null){
                byte[] command = Utils.decodeBitmap(bmp);
                printText(command);
            }else{
                Log.e("Print Photo error", "the file isn't exists");
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("PrintTools", "the file isn't exists");
        }
    }

关于java - 如何在 Android 的蓝牙打印机上打印图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14530058/

相关文章:

java - 适用于初学者的OSGi教程,具有最新的工具版本

java - Platform.exit() 在 JavaFX 的无限循环中无效

java - 使用 Apache Wink 覆盖 Websphere 8.5.5 上的 Jackson Object Mapper 属性

android - 如何显示位图资源与使用形状绘制命令?

java - 应用程序似乎卡在 SocketRead 上

android - 在 Android 中创建元素周期表

android - Intent 查看特定事件实例的日历

java - Bitmap 到 Byte[] 转换的更快方法

android - 如何在没有 OutOfMemory 和 "Bitmap too large to be uploaded into a texture (1840x3264, max=2048x2048)"的情况下以图标形式从磁盘下载照片

c++ - 组合位图 - GDI/GDI+?