def from_pdf(
        cls, pdf, filename, width=288, height=432, dpi=203, font_path=None,
        center_of_pixel=False, use_bindings=False
    ):
        """
        Filename is 1-8 alphanumeric characters to identify the GRF in ZPL.

        Dimensions and DPI are for a typical 4"x6" shipping label.
        E.g. 432 points / 72 points in an inch / 203 dpi = 6 inches

        Using center of pixel will improve barcode quality but may decrease
        the quality of some text.

        use_bindings=False:
            - Uses subprocess.Popen
            - Forks so there is a memory spike
            - Easier to setup - only needs the gs binary

        use_bindings=True:
            - Uses python-ghostscript
            - Doesn't fork so should use less memory
            - python-ghostscript is a bit buggy
            - May be harder to setup - even if you have updated the gs binary
              there may stil be old libgs* files on your system
        """

        # Most arguments below are based on what CUPS uses
        setpagedevice = [
            '/.HWMargins[0.000000 0.000000 0.000000 0.000000]',
            '/Margins[0 0]'
        ]

        cmd = [
            'gs',
            '-dQUIET',
            '-dPARANOIDSAFER',
            '-dNOPAUSE',
            '-dBATCH',
            '-dNOINTERPOLATE',
            '-sDEVICE=pngmono',
            '-dAdvanceDistance=1000',
            '-r%s' % int(dpi),
            '-dDEVICEWIDTHPOINTS=%s' % int(width),
            '-dDEVICEHEIGHTPOINTS=%s' % int(height),
            '-dFIXEDMEDIA',
            '-dPDFFitPage',
            '-c',
            '<<%s>>setpagedevice' % ' '.join(setpagedevice)
        ]

        if center_of_pixel:
            cmd += ['0 .setfilladjust']

        if font_path and os.path.exists(font_path):
            cmd += ['-I' + font_path]

        if use_bindings:
            import ghostscript
            # python-ghostscript doesn't like reading/writing from
            # stdin/stdout so we need to use temp files
            with tempfile.NamedTemporaryFile() as in_file, \
                 tempfile.NamedTemporaryFile() as out_file:

                in_file.write(pdf)
                in_file.flush()

                # Ghostscript seems to be sensitive to argument order
                cmd[13:13] += [
                    '-sOutputFile=%s' % out_file.name
                ]
                cmd += [
                    '-f', in_file.name
                ]

                try:
                    ghostscript.Ghostscript(*[c.encode('ascii') for c in cmd])
                except Exception as e:
                    raise GRFException(e)

                pngs = out_file.read()
        else:
            from subprocess import PIPE, Popen
            # Ghostscript seems to be sensitive to argument order
            cmd[13:13] += [
                '-sstdout=%stderr',
                '-sOutputFile=%stdout',
            ]
            cmd += [
                '-f', '-'
            ]
            p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
            pngs, stderr = p.communicate(pdf)
            if stderr:
                raise GRFException(stderr)

        # This is what PIL uses to identify PNGs
        png_start = b'\211PNG\r\n\032\n'

        grfs = []
        for png in pngs.split(png_start)[1:]:
            grfs.append(cls.from_image(png_start + png, filename))
        return grfs
Filename is 1-8 alphanumeric characters to identify the GRF in ZPL.

        Dimensions and DPI are for a typical 4"x6" shipping label.
        E.g. 432 points / 72 points in an inch / 203 dpi = 6 inches

        Using center of pixel will improve barcode quality but may decrease
        the quality of some text.

        use_bindings=False:
            - Uses subprocess.Popen
            - Forks so there is a memory spike
            - Easier to setup - only needs the gs binary

        use_bindings=True:
            - Uses python-ghostscript
            - Doesn't fork so should use less memory
            - python-ghostscript is a bit buggy
            - May be harder to setup - even if you have updated the gs binary
              there may stil be old libgs* files on your system