2014-10-09 142 views
10

我試圖在支持ESC命令的熱敏打印機中打印576像素寬度的圖像,問題在於命令「ESC *」爲打印圖像位只讓我打印寬度爲255像素的圖像(如果我使用576像素的圖像打印某些部分,其餘部分是隨機符號),在文檔中說,這些命令最多接受255個字節,如下所示:在熱點打印機中使用ESC中的ESC/POS打印位圖全頁寬度

ESC * m nL nH d1Ödk 
Name Specify bit image mode 
Code ASCII ESC * m nL nHd1...dk 
Hex. 1B 2A m nL nHd1...dk 
Decimal 27 42 m nL nHd1...dk 
Defined Region m = 0,1,32,33 
0 ≤ nL ≤ 255 
0 ≤ nH ≤ 3 
0 ≤ d ≤ 255 

,所以我不知道如何打印圖像,將打印機頁(576像素),我有這個代碼,打印圖像的寬度最大:

public class ESCPOSApi { 

    private final byte[] INITIALIZE_PRINTER = new byte[]{0x1B,0x40}; 

    private final byte[] PRINT_AND_FEED_PAPER = new byte[]{0x0A}; 

    private final byte[] SELECT_BIT_IMAGE_MODE = new byte[]{(byte)0x1B, (byte)0x2A}; 
    private final byte[] SET_LINE_SPACING = new byte[]{0x1B, 0x33}; 

    private FileOutputStream printOutput; 

    public int maxBitsWidth = 255; 

    public ESCPOSApi(String device) { 
     try { 
      printOutput = new FileOutputStream(device); 
     } catch (FileNotFoundException ex) { 
      Logger.getLogger(ESCPOSApi.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    private byte[] buildPOSCommand(byte[] command, byte... args) { 
     byte[] posCommand = new byte[command.length + args.length]; 

     System.arraycopy(command, 0, posCommand, 0, command.length); 
     System.arraycopy(args, 0, posCommand, command.length, args.length); 

     return posCommand; 
    } 

    private BitSet getBitsImageData(BufferedImage image) { 
     int threshold = 127; 
     int index = 0; 
     int dimenssions = image.getWidth() * image.getHeight(); 
     BitSet imageBitsData = new BitSet(dimenssions); 

     for (int y = 0; y < image.getHeight(); y++) 
     { 
      for (int x = 0; x < image.getWidth(); x++) 
      { 
       int color = image.getRGB(x, y); 
       int red = (color & 0x00ff0000) >> 16; 
       int green = (color & 0x0000ff00) >> 8; 
       int blue = color & 0x000000ff; 
       int luminance = (int)(red * 0.3 + green * 0.59 + blue * 0.11); 
       //dots[index] = (luminance < threshold); 
       imageBitsData.set(index, (luminance < threshold)); 
       index++; 
      } 
     } 

     return imageBitsData; 
    } 

    public void printImage(BufferedImage image) { 
     try { 
      BitSet imageBits = getBitsImageData(image); 

      byte widthLSB = (byte)(image.getWidth() & 0xFF); 
      byte widthMSB = (byte)((image.getWidth() >> 16) & 0xFF); 

      // COMMANDS 
      byte[] selectBitImageModeCommand = buildPOSCommand(SELECT_BIT_IMAGE_MODE, (byte) 33, widthLSB, widthMSB); 
      byte[] setLineSpacing24Dots = buildPOSCommand(SET_LINE_SPACING, (byte) 24); 
      byte[] setLineSpacing30Dots = buildPOSCommand(SET_LINE_SPACING, (byte) 30); 


      printOutput.write(INITIALIZE_PRINTER); 
      printOutput.write(setLineSpacing24Dots); 

      int offset = 0; 
      while (offset < image.getHeight()) { 
       printOutput.write(selectBitImageModeCommand); 

       int imageDataLineIndex = 0; 
       byte[] imageDataLine = new byte[3 * image.getWidth()]; 

       for (int x = 0; x < image.getWidth(); ++x) { 

        // Remember, 24 dots = 24 bits = 3 bytes. 
        // The 'k' variable keeps track of which of those 
        // three bytes that we're currently scribbling into. 
        for (int k = 0; k < 3; ++k) { 
         byte slice = 0; 

         // A byte is 8 bits. The 'b' variable keeps track 
         // of which bit in the byte we're recording. 
         for (int b = 0; b < 8; ++b) { 
          // Calculate the y position that we're currently 
          // trying to draw. We take our offset, divide it 
          // by 8 so we're talking about the y offset in 
          // terms of bytes, add our current 'k' byte 
          // offset to that, multiple by 8 to get it in terms 
          // of bits again, and add our bit offset to it. 
          int y = (((offset/8) + k) * 8) + b; 

          // Calculate the location of the pixel we want in the bit array. 
          // It'll be at (y * width) + x. 
          int i = (y * image.getWidth()) + x; 

          // If the image (or this stripe of the image) 
          // is shorter than 24 dots, pad with zero. 
          boolean v = false; 
          if (i < imageBits.length()) { 
           v = imageBits.get(i); 
          } 
          // Finally, store our bit in the byte that we're currently 
          // scribbling to. Our current 'b' is actually the exact 
          // opposite of where we want it to be in the byte, so 
          // subtract it from 7, shift our bit into place in a temp 
          // byte, and OR it with the target byte to get it into there. 
          slice |= (byte) ((v ? 1 : 0) << (7 - b)); 
         } 

         imageDataLine[imageDataLineIndex + k] = slice; 

         // Phew! Write the damn byte to the buffer 
         //printOutput.write(slice); 
        } 

        imageDataLineIndex += 3; 
       } 

       printOutput.write(imageDataLine); 
       offset += 24; 
       printOutput.write(PRINT_AND_FEED_PAPER); 
      } 


      printOutput.write(setLineSpacing30Dots); 
     } catch (IOException ex) { 
      Logger.getLogger(ESCPOSApi.class 
        .getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

我想使用24點雙密度,但現在我使用24點單密度與255像素圖像(這讓我打印圖像在整個頁面寬度,但我需要雙倍密度)

+0

image.getWidth()>> 16 ---應該是「>> 8」。每字節8位。 – joeking 2014-10-09 04:37:11

+0

嘿joeking發表您的評論作爲答案,這解決了我的問題:D – 2014-10-09 13:11:10

回答

9

在上面的代碼中,

image.getWidth()>> 16 ---應該是「>> 8」。每字節8位。

相關問題