Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use full page width with Brother P950NW

I would like to use the full width of the 18mm strips in my Brother P950NW printer for an image. At the moment, I am using ESC/P (not ESC/POS, which this printer does not seem to support), but if it's not possible with that I'm fine with any other protocol this printer supports. (Update: with Brother's Windows software, full-width printing is possible, but it uses the LPR protocol, for which there don't seem to be any Python libraries.)

I'm using the ESC/P command ESC* with density 72 (the highest available according to the printer's documentation), which only allows filling up the width in steps of 48 dots.

How do I print 200 pixels wide on a strip in ESC/P-speak an image with height 200? That should easily fit onto the strip. However, due to ESC*72 only accepting blocks of 48, everything beyond 192 is output on another strip.

Here's my demo code:

import socket
import struct

def escp(density_code=72):
    stack_size_in_bytes = {72: 6}[density_code]
    height = 200
    width = 130

    yield b'\x1bia\x00'  # ESC/P command mode: ESC/P standard
    yield b'\x1b@'  # Initialize
    yield b'\x1bim\x00\x00'  # margin: 0
    yield b'\x1biXE2\x00\x00\x00'  # barcode margin: 0
    yield b'\x1b3' + struct.pack('!B', 24)  # line feed length: 24 dots (i.e. no space between lines)

    for y_offset in range(0, height, 8 * stack_size_in_bytes):
        yield b'\x1b*' + struct.pack('!B', density_code) + struct.pack('<H', width)
        yield b'\xff' * width * stack_size_in_bytes
        yield b'\x0a'  # linefeed (move position 24 dots down)
    yield b'\x0c' # Print start

c = socket.create_connection(('10.222.2.206', 9100))
c.sendall(b''.join(escp()))
c.close()

I'm fine with solutions in raw binary; here is the binary file and shortened hexdump generated by the above program.

like image 639
phihag Avatar asked Apr 19 '18 20:04

phihag


2 Answers

Both the Brother PT-P950NW and Borther PT-9800PCN support a "raster protocol" (code 1 instead of 0 after ESC iA). With this protocol, it is possible to print raster graphics at full width.

However, I could not find any documentation (the closest was this PDF for another printer), so I reverse-engineered it (and tried out a lot). The result is the project rasterprynt, available as a PyPi package. With rasterprynt, you can print arbitrary images, like this:

import rasterprynt

import PIL.Image

# Enter the IP address of your printer below
printer_ip = '192.168.1.123'

img1 = PIL.Image.open('example1.png')
img2 = PIL.Image.open('example2.png')
data = rasterprynt.prynt([img1, img2, img1], printer_ip)
like image 162
phihag Avatar answered Oct 23 '22 04:10

phihag


Base the page 8 of the DOC,we can specify the print position before print one line, and even with image ,it will print one line by one line.ESC $can specify absolute horizontal position and ESC J will Finishes input of the current line, then moves the vertical print position forward by n/180 inch.combine this two,maybe you can using all 234 printable area.

import socket
import struct

def escp(density_code=72):
    stack_size_in_bytes = {72: 6}[density_code]
    height = 200
    width = 130

    yield b'\x1bia\x00'  # ESC/P command mode: ESC/P standard
    yield b'\x1b@'  # Initialize
    yield b'\x1bim\x00\x00'  # margin: 0
    yield b'\x1biXE2\x00\x00\x00'  # barcode margin: 0
    yield b'\x1b3' + struct.pack('!B', 24)  # line feed length: 24 dots (i.e. no space between lines)

    for y_offset in range(0, height, 8 * stack_size_in_bytes):
        yield b'\x1b*' + struct.pack('!B', density_code) + struct.pack('<H', width)
        yield b'\xff' * width * stack_size_in_bytes
        # the added command ECS J
        yield b'\x1b4a' + struct.pack('!B', 42)
        # ESC $ is b'1b24'+struct.pack('!B', 0)+struct.pack('!B', 0)
        yield b'\x0a'  # linefeed (move position 24 dots down)
    yield b'\x0c' # Print start

c = socket.create_connection(('10.222.2.206', 9100))
c.sendall(b''.join(escp()))
c.close()

b'\x1b4a' + struct.pack('!B', 42)isESC J Forward paper feed

ASCII: ESC J n

Decimal: 27 74 n

Hexadecimal: 1B 4A n

Parameters

0≤n≤255

Description

 Finishes input of the current line, then moves the vertical print position forward by n/180 inch.

 If n is less than 24, the feed amount is 24/180 inch (approximately 0.34 cm).

b'1b24'+struct.pack('!B', 0)+struct.pack('!B', 0)is ESC $ Specify absolute horizontal position

ASCII: ESC $ n1 n2

Decimal: 27 36 n1 n2

Hexadecimal: 1B 24 n1 n2

Parameters

0≤n1≤255, 0≤n2≤255

Description

 Specifies an absolute print position (in units of 1/60 inch) for the next data.

 An absolute print position specifies the horizontal print position from the left margin.

 The next character is printed at a position (n1 + 256 * n2) / 60 inch from the left margin.

 The maximum number of dots can be specified by both n1 and n2 is 1023/60 inches.

like image 1
obgnaw Avatar answered Oct 23 '22 02:10

obgnaw