title: How can I print an image on a Bluetooth printer in Android?
body: <p>I have to print some data on thermal bluetooth printer, I'm doing with this:</p>
  
  <pre><code>String message="abcdef any message 12345";
  byte[] send;
  send = message.getBytes();
  mService.write(send);
  </code></pre>
  
  <p>It works well for text, but not for images. I think I need to get the <code>byte[]</code> of the image data. I tried getting the data of the image this way:</p>
  
  <pre><code>Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.qrcode);
  ByteArrayOutputStream stream=new ByteArrayOutputStream();
  bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
  byte[] image=stream.toByteArray();
  </code></pre>
  
  <p>Unfortunately the printer prints a lot of strange characters (approx. 50 cm of paper). I don't know how to print the image. </p>
  
  <p>I would like to try getting the pixels of the bitmap and next converting it to a <code>byte[]</code> and sending it, but i don't know how to do it. </p>
  
  <p>Thanks</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>After so much time, i'm doing this: I have a method called print_image(String file), the which gets the path of the image that i want to print:</p>
  
  <pre><code>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 &lt; bmp.getHeight()) {
              mService.write(PrinterCommands.SELECT_BIT_IMAGE_MODE);
              for (int x = 0; x &lt; bmp.getWidth(); ++x) {
  
                  for (int k = 0; k &lt; 3; ++k) {
  
                      byte slice = 0;
                      for (int b = 0; b &lt; 8; ++b) {
                          int y = (((offset / 8) + k) * 8) + b;
                          int i = (y * bmp.getWidth()) + x;
                          boolean v = false;
                          if (i &lt; dots.length()) {
                              v = dots.get(i);
                          }
                          slice |= (byte) ((v ? 1 : 0) &lt;&lt; (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();
      }
  }
  </code></pre>
  
  <p>I did it based on this <a href="http://android-essential-devtopics.blogspot.com/2013/02/sending-bit-image-to-epson-printer.html" rel="noreferrer">post</a></p>
  
  <p>This is the class PrinterCommands:</p>
  
  <pre><code>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};
  }
  </code></pre>
  
  <p>As is seen in the print_image method I'm calling a method, called convertBitmap, and im sending a bitmap, this is the code:</p>
  
  <pre><code>   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 &lt; height; x++) {
              for (int y = 0; y &lt; 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 &lt; 55) {                       
                      dots.set(k);//this is the bitset that i'm printing
                  }
                  k++;
  
              }
  
  
          }
  
  
      } catch (Exception e) {
          // TODO: handle exception
          Log.e(TAG, e.toString());
      }
  }
  </code></pre>
  
  <p>This is the <a href="http://www.rgprt.com/En/Products_show_53.html" rel="noreferrer">printer</a> that i'm using, resolution: 8 dots/mm, 576 dots/line</p>
  
  <p>And this is what I like to do (i did it with the same printer, but with an app downloaded from play store)
  <img src="https://i.stack.imgur.com/pIb37.jpg" alt="Image that I want to print"></p>
  
  <p>This is what i'm getting now
  <img src="https://i.stack.imgur.com/nYoOZ.jpg" alt="My printing trying"></p>
  
  <p>Closer:
  <img src="https://i.stack.imgur.com/PmQop.jpg" alt="A closer part"></p>
  
  <p>Closer2:
  <img src="https://i.stack.imgur.com/cRa98.jpg" alt="enter image description here"></p>
  
  <p>A little part of the image can be seen, so I think that i'm closer to can print the image... </p>
  
  <p>The image that i'm using is this (576x95):<img src="https://i.stack.imgur.com/DKu6f.png" alt="enter image description here"></p>
  
  <p>And this is the converted image (i'm converting it with the upper code):
  <img src="https://i.stack.imgur.com/oiRVe.png" alt="converted image"></p>
  
  <p><img src="https://i.stack.imgur.com/SIz4L.png" alt="Inverted "></p>
  
  <p>So, the answer is: what I'm doing wrong?, I think that the error is in this command:</p>
  
  <pre><code>  public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 33, -128, 0};
  </code></pre>
  
  <p>But, how can I calculate the correct values for my image?, thanks</p>