brother_ql icon indicating copy to clipboard operation
brother_ql copied to clipboard

Printing PDFs from brother_ql

Open alfiepates opened this issue 5 years ago • 2 comments

Resurrecting something discussed in issue #24:

I'm working on a project to interface a QL-series printer with a network application: it's pretty generic, but TL;DR; a user presses a button, an API call is made across the network, and a label with today's date and a date two weeks in the future pops out of a printer.

I'm using reportlab's pdfgen to typeset the labels because it's quick and simple an I really don't like working with PIL. I have this setup spitting out nicely typeset little 62mm*40mm PDFs, but his leaves me with a problem: brother_ql doesn't yet take PDFs, so I have to munge the PDFs into PNGs to make this happen.

I'm currently shelling out to poppler-utils with a kludgy bit of code to turn PDFs into PNGs. This works fine for my usecase (I've effectively hardcoded the fact I'm turning single-page 62mm*40mm PDFs into 300DPI PNGs) but it's a little bit gross, and I feel like this functionality could conceivably live inside brother_ql?

I'm quite happy with using poppler-utils for this purpose: it's available cross-platform, it's pretty fast, and it generates decent results. It is an external dependency, however, but it would only be required if printing PDFs.

(Subsequently to writing that kludge, I discovered pdf2image, which basically does the shelling out to poppler-utils but with an understanding of pages and stuff, which seems to massively simplify the task)

I can't speak for what I'd want the CLI to look like, since I only really interface with brother_ql as a library from my own code. I'd imagine that passing a PDF instead of a PNG would just convert the PDF at whatever DPI is selected, error if the PDF page size doesn't match the label stock selected, and loop through multi-page PDFs - I wouldn't imagine there's much that couldn't be handled (at least initially) by the existing flags for printing images.

alfiepates avatar Aug 22 '19 22:08 alfiepates

Hi @alfiepates,

you can use the ReportLAB's renderPM class method drawToPIL to convert a Drawing instance to a PIL Image instance.

Example (tested on QL-700):

from reportlab.graphics.shapes import Drawing, String
from reportlab.graphics import renderPM

from brother_ql.devicedependent import label_type_specs
from brother_ql import BrotherQLRaster, create_label
from brother_ql.backends.helpers import send

PRINTER = 'usb://0x04f9:0x2042'
LABEL_NAME = '29x90'
DPI_600 = True

width = label_type_specs[LABEL_NAME]['dots_printable'][1] * 2      # Multiply by 2 for 600dpi
height = label_type_specs[LABEL_NAME]['dots_printable'][0] * 2     # Multiply by 2 for 600dpi

d = Drawing(width, height)
d.add(String(15, height-300, 'TEST', fontSize=300, fontName='Helvetica'))
d.add(String(15, height-500, '600dpi', fontSize=100, fontName='Helvetica'))

qlr = BrotherQLRaster('QL-700')
create_label(qlr, renderPM.drawToPIL(d), LABEL_NAME, cut=True, rotate=90, dpi_600=DPI_600)
send(qlr.data, PRINTER)

stigchristian avatar Sep 02 '19 21:09 stigchristian

@stigchristian I don't know how I missed this, I must have read the reportlab documentation three or four times at this point. Thank you very much for the solution to my particular problem!

alfiepates avatar Sep 03 '19 20:09 alfiepates