Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generating multiple barcodes without reopening the gs subprocess? #145

Open
dlenski opened this issue Jan 13, 2019 · 4 comments
Open

Generating multiple barcodes without reopening the gs subprocess? #145

dlenski opened this issue Jan 13, 2019 · 4 comments

Comments

@dlenski
Copy link
Contributor

dlenski commented Jan 13, 2019

I'm trying to figure out whether there's a reasonable way to generate multiple barcode images without reopening the gs subprocess and reinterpreting the BWIPP source — which are rather "heavyweight" and slow operations.

It seems like this should be eminently possible. See below: ./multi_barcode.py (run as multi_barcode.py "bc1" "bc2" ....

Problems I'm having:

  1. I can't figure out how to make this work with EPS, because the eps2write driver doesn't like switching output files.
  2. I can't figure out how to measure the bounding box and output the correct-sized image in a single pass.
#!/usr/bin/python3

from treepoem import BWIPP
from binascii import hexlify
import os, sys, subprocess, time

ghostscript = 'gs'
barcode_ps = '/home/dlenski/build/treepoem/treepoem/postscriptbarcode/barcode.ps'

gs_process = subprocess.Popen(
    [ghostscript,  '-dNOPAUSE', '-sDEVICE=pngmono', '-q'],
    universal_newlines=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
)
gs_process.stdin.write('<{}> run\n'.format(hexlify(barcode_ps.encode()).decode()))

for ii, code in enumerate(sys.argv[1:]):
    ofn = '/tmp/test-%d.png' % ii
    options = 'includetext'
    symbology = 'code128'

    print("Generating barcode for %s to file %s" % (code, ofn))
    try: os.unlink(ofn)
    except: pass
    
    fields = {k:hexlify(v.encode()).decode() for k,v in {'ofn':ofn, 'code':code, 'options':options, 'symbology':symbology}.items()}
    gs_process.stdin.write('''
        << /OutputFile <{ofn}> >> setpagedevice
        /Helvetica findfont 10 scalefont setfont
        gsave
        2 2 scale
        10 10 moveto

        <{code}> <{options}> <{symbology}> cvn
        /uk.co.terryburton.bwipp findresource exec
        grestore

        showpage
        '''.format(**fields))
    try:
        gs_process.stdin.flush()
    except:
        print(gs_process.communicate())

    st = None
    for ii in range(4):
        try:
            st = os.stat(ofn)
        except FileNotFoundError:
            time.sleep(1)
        else:
            break
    if not st:
        print("ERROR: File %s not created after %d seconds." % (ofn, ii))
    else:
        print("OKAY: File %s (%dB) created after %d seconds." % (ofn, st.st_size, ii))
    
else:
    stdout, stderr = gs_process.communicate()
    print("STDOUT: %s" % stdout)
    print("STDERR: %s" % stderr)
@adamchainz
Copy link
Owner

Hi Dan

I am afraid I can't really help with this. I don't actively use treepoem any more. Would you like to become a maintainer?

Adam

@dlenski
Copy link
Contributor Author

dlenski commented Jan 14, 2019

Ah, too bad! Yes, that would be useful… though it also means I'll have to figure out all the problems on my own 😂

@adamchainz
Copy link
Owner

I've invited you as a collaborator on GitHub. If you don't mind I'll still keep doing maintenance work like updating the requirements and doing releases, but other than that feel free to make code changes, I'll try make myself available to review PR's.

But yes enjoy trying to make the optimization of a single ghostscript, it would be a big performance boost.

@adamchainz
Copy link
Owner

I'm more actively maintaining treepoem now. I just merged #499 which removes using the PIL EPS plugin to run Ghostscript, so now treepoem is the only thing running Ghostscript.

From here I think we may be able to move to a single process model. There may be some difficulty as the bounding box template and rendering postscript templates use different headers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants