title: Ionic 3: Print image using Bluetooth printer
body: <p>I am currently struggling with our Ionic3 app. I can't seem to find out how to print an image using BT printer and Bluetooth Serial plugin. Printing text is just fine. </p>
  
  <p>We are testing RPP02N-BU printer using this documentation (found by my ex-colleague)
  <a href="https://www.sparkfun.com/datasheets/Components/General/Driver%20board.pdf" rel="nofollow noreferrer">Driver Commands Documentation</a>, but I can not get the </p>
  
  <blockquote>
    <p>SELECT BIT IMAGE MODE</p>
  </blockquote>
  
  <p>to work.</p>
  
  <p>We first resize uploaded image to not exceed 300px and we convert it to Black and White. When printing, we iterate the image and create binary strings, which we then convert to bytes. Those bytes follow the SELECT BIT IMAGE MODE commands.</p>
  
  <p>Our code (in TypeScript) is as follows:</p>
  
  <pre><code>/**
   * Image to printer command
   * @param image 
   */
  public static getImagePrintData(image: HTMLImageElement): Buffer {
      // Initialize list of commands
      let command: number[] = [ 0x1b, 0x2a, 33, 255, 3 ];
  
      // Get image bytes
      let bytes = this.getImageBytes(image);
  
      // Add bytes to command
      bytes.forEach((byte) =&gt; command.push(byte));
  
      // Return command
      return new Buffer(command);
  }
  
  /**
   * Get image bytes
   * @param image 
   */
  private static getImageBytes(image: HTMLImageElement): number[] {
      // Init result
      let result = [];
  
      // Create image padding
      let padding = this.getZeroBytePadding(image.width);
  
      // Get image context
      let ctx = this.getImageContext(image);
  
      // Iterate image pixels
      for (let y = 0; y &lt; image.height; y++) {
          // Init row string
          let row = "";
  
          // Go through row of pixels
          for (let x = 0; x &lt; image.width; x++) {
              // Get pixel
              let pixel = ctx.getImageData(x, y, 1, 1).data;
  
              // Get rgb value
              let rgbValue = pixel[0] + pixel[1] + pixel[2];
  
              // Add 0 or 1 based on value
              row = row + (rgbValue &gt; 0 ? 0 : 1);
          }
  
          // Add padding
          row = row + padding;
  
          // Now we need to split the row into byte chunks
          let byteChunks = row.match(/.{1,8}/g);
  
          // Now add those byte chunks to result
          byteChunks.forEach((chunk) =&gt; result.push(parseInt(chunk, 2)));
      }
  
      // Return result
      return result;
  }
  
  /**
   * Get zero byte padding
   * @param value 
   */
  private static getZeroBytePadding(value: number): string {
      // Init padding
      let padding = "";
  
      // Get difference
      let diff = value % 8;
  
      // Create padding
      for (let i = 0; i &lt; (8 - diff); i++) {
          padding = padding + "0";
      }
  
      // Return result
      return padding;
  }
  
  /**
   * Get image context
   * @param image 
   */
  private static getImageContext(image: HTMLImageElement): CanvasRenderingContext2D {
      // Prepare canvas to draw image into
      var canvas = document.createElement('canvas');
      canvas.width = image.width;
      canvas.height = image.height;
  
      // Context
      var ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0);
  
      return ctx;
  }
  </code></pre>
  
  <p>Then the command is sent to BT printer:</p>
  
  <pre><code>// Initialize image
  let image = new Image();
  // Set data
  image.src = options.logo.content;
  // Get image print data
  let imagePrintData = PrinterUtils.getImagePrintData(image);
  
  // Push image to print queue
  printQueue.push(this.bluetoothUtility.write(imagePrintData));
  </code></pre>
  
  <p>The resulting image looks like this:</p>
  
  <p><a href="https://i.stack.imgur.com/1T2kH.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1T2kH.jpg" alt="Printed image"></a></p>
  
  <p>And the original is:</p>
  
  <p><a href="https://i.stack.imgur.com/4RwAa.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4RwAa.png" alt="Original image"></a></p>