Python Forum
Universal(MACWINLIN) canvas pdf export
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Universal(MACWINLIN) canvas pdf export
#5
(Aug-12-2022, 11:26 AM)Gribouillis Wrote: I would try to draw in parallel a PIL image and the tkinter canvas like in this very old forum post. The pil image can be saved as pdf in modern versions of pil. You could define your own functions such as

def my_create_rectangle(...):
    my_canvas.create_rectangle(...)
    my_image.rectangle(...)

...
def generate_drawing():
    ...
    my_create_rectangle(...)

def generate_pdf(...)
    my_image.save(...) # save as pdf

A long time since this answer. Sorry I didn't react earlier. But I found after a long time a solution for this for mac windows and linux. Pil is not a real solution since My output needs to be a vector drawing for the best print quality.

for all three systems I needed to use a external command line program to make a conversion between .ps and .pdf:
def exportPDF(event=''):    
    def is_tool(name):
        """Check whether `name` is on PATH and marked as executable."""
        return which(name) is not None
        print('exportPDF')

    if platform.system() == 'Linux':
        if is_tool('ps2pdfwr') == 0:
            messagebox.showinfo(title="Can't export PDF!",
                                message='PianoScript cannot export the PDF because function "ps2pdfwr" is not '
                                        'installed on your computer.')
            return

        f = filedialog.asksaveasfile(mode='w', parent=root, filetypes=[("pdf file", "*.pdf")], initialfile=Score['header']['title']['text'],
                                     initialdir='~/Desktop')
        if f:
            pslist = []
            if Score['properties']['engraver'] == 'pianoscript':
                numofpages = range(engrave_pianoscript('export',
                    renderpageno,
                    Score,
                    MM,
                    last_pianotick,
                    color_notation_editor,
                    color_editor_canvas,
                    pview,root,
                    BLACK))
                for rend in numofpages:
                    pview.postscript(file=f"/tmp/tmp{rend}.ps", 
                        x=10000,
                        y=rend * (Score['properties']['page-height'] * MM), 
                        width=Score['properties']['page-width'] * MM,
                        height=Score['properties']['page-height'] * MM, 
                        rotate=False,
                        fontmap='-*-Courier-Bold-R-Normal--*-120-*')
                    process = subprocess.Popen(
                        ["ps2pdfwr", "-sPAPERSIZE=a4", "-dFIXEDMEDIA", "-dEPSFitPage", "/tmp/tmp%s.ps" % rend,
                         "/tmp/tmp%s.pdf" % rend])
                    process.wait()
                    os.remove("/tmp/tmp%s.ps" % rend)
                    pslist.append("/tmp/tmp%s.pdf" % rend)
            else:
                numofpages = range(engrave_pianoscript_vertical('export',
                    renderpageno,
                    Score,
                    MM,
                    last_pianotick,
                    color_notation_editor,
                    color_editor_canvas,
                    pview,root,
                    BLACK))
                for rend in numofpages:
                    pview.postscript(file=f"/tmp/tmp{rend}.ps", 
                        x=rend * (Score['properties']['page-width'] * MM),
                        y=10000, 
                        width=Score['properties']['page-width'] * MM,
                        height=Score['properties']['page-height'] * MM, 
                        rotate=False,
                        fontmap='-*-Courier-Bold-R-Normal--*-120-*')
                    process = subprocess.Popen(
                        ["ps2pdfwr", "-sPAPERSIZE=a4", "-dFIXEDMEDIA", "-dEPSFitPage", "/tmp/tmp%s.ps" % rend,
                         "/tmp/tmp%s.pdf" % rend])
                    process.wait()
                    os.remove("/tmp/tmp%s.ps" % rend)
                    pslist.append("/tmp/tmp%s.pdf" % rend)
            cmd = 'pdfunite '
            for i in range(len(pslist)):
                cmd += pslist[i] + ' '
            cmd += '"%s"' % f.name
            process = subprocess.Popen(cmd, shell=True)
            process.wait()

    elif platform.system() == 'Windows':
        f = filedialog.asksaveasfile(mode='w', parent=root, filetypes=[("pdf Score", "*.pdf")], initialfile=Score['header']['title']['text'],
                                     initialdir='~/Desktop')
        if f:
            pslist = []
            if Score['properties']['engraver'] == 'pianoscript':
                print(f.name)
                counter = 0
                numofpages = range(engrave_pianoscript('export',
                        renderpageno,
                        Score,
                        MM,
                        last_pianotick,
                        color_notation_editor,
                        color_editor_canvas,
                        pview,root,
                        BLACK))
                for export in numofpages:
                    counter += 1
                    print('printing page ', counter)
                    pview.postscript(file=f"{f.name}{counter}.ps", 
                        colormode='gray', 
                        x=10000, 
                        y=export * (Score['properties']['page-height'] * MM),
                        width=(Score['properties']['page-width'] * MM), 
                        height=(Score['properties']['page-height'] * MM), 
                        rotate=False,
                        fontmap='-*-Courier-Bold-R-Normal--*-120-*')
                    pslist.append(str('"' + str(f.name) + str(counter) + '.ps' + '"'))
                try:
                    do_rend = subprocess.Popen(
                        f'''"C:/Program Files/gs/gs10.01.1/bin/gswin64c.exe" -dQUIET -dBATCH -dNOPAUSE -dFIXEDMEDIA -sPAPERSIZE=a4 -dEPSFitPage -sDEVICE=pdfwrite -sOutputFile="{f.name}.pdf" {' '.join(pslist)}''', shell=True)
                    do_rend.wait()
                    do_rend.terminate()    
                    for i in pslist:
                        os.remove(i.strip('"'))
                    f.close()
                    os.remove(f.name)
                except:
                    messagebox.showinfo(title="Can't export PDF!",
                                        message='''Be sure you have selected a valid path to "gswin64c.exe" in the gspath.json file that is located in the same folder as PianoScript program. You have to set the path+gswin64c.exe. example: "gspath":"C:/Program Files/gs/gs9.54.0/bin/gswin64c.exe". Then, restart PianoScript app.''')
            else:
                print(f.name)
                counter = 0
                numofpages = range(engrave_pianoscript_vertical('export',
                        renderpageno,
                        Score,
                        MM,
                        last_pianotick,
                        color_notation_editor,
                        color_editor_canvas,
                        pview,root,
                        BLACK))
                for export in numofpages:
                    counter += 1
                    print('printing page ', counter)
                    pview.postscript(file=f"{f.name}{counter}.ps", 
                        colormode='gray', 
                        x=export * (Score['properties']['page-width'] * MM), 
                        y=10000,
                        width=(Score['properties']['page-width'] * MM), 
                        height=(Score['properties']['page-height'] * MM),
                        rotate=False,
                        fontmap='-*-Courier-Bold-R-Normal--*-120-*')
                    pslist.append(str('"' + str(f.name) + str(counter) + '.ps' + '"'))
                try:
                    do_rend = subprocess.Popen(
                        f'''"C:/Program Files/gs/gs10.01.1/bin/gswin64c.exe" -dQUIET -dBATCH -dNOPAUSE -dFIXEDMEDIA -sPAPERSIZE=a4 -dEPSFitPage -sDEVICE=pdfwrite -sOutputFile="{f.name}.pdf" {' '.join(pslist)}''', shell=True)
                    do_rend.wait()
                    do_rend.terminate()    
                    for i in pslist:
                        os.remove(i.strip('"'))
                    f.close()
                    os.remove(f.name)
                except:
                    messagebox.showinfo(title="Can't export PDF!",
                                        message='''Be sure you have selected a valid path to "gswin64c.exe" in the gspath.json file that is located in the same folder as PianoScript program. You have to set the path+gswin64c.exe. example: "gspath":"C:/Program Files/gs/gs9.54.0/bin/gswin64c.exe". Then, restart PianoScript app.''')
    
    elif platform.system() == 'Darwin':
        f = filedialog.asksaveasfile(mode='w', parent=root, 
                                     filetypes=[("pdf Score", "*.pdf")], 
                                     initialfile=Score['header']['title']['text'],
                                     initialdir='~/Desktop')
        if f:
            pslist = []
            if Score['properties']['engraver'] == 'pianoscript':
                numofpages = range(engrave_pianoscript('export',
                    renderpageno,
                    Score,
                    MM,
                    last_pianotick,
                    color_notation_editor,
                    color_editor_canvas,
                    pview,root,
                    BLACK))
                for rend in numofpages:
                    pview.postscript(file=f"/tmp/tmp{rend}.ps", 
                        x=10000,
                        y=rend * (Score['properties']['page-height'] * MM), 
                        width=Score['properties']['page-width'] * MM,
                        height=Score['properties']['page-height'] * MM, 
                        rotate=False,
                        fontmap='-*-Courier-Bold-R-Normal--*-120-*')
                    process = subprocess.Popen(
                        ["ps2pdfwr", "-sPAPERSIZE=a4", "-dFIXEDMEDIA", "-dEPSFitPage", "/tmp/tmp%s.ps" % rend,
                         "/tmp/tmp%s.pdf" % rend])
                    process.wait()
                    os.remove("/tmp/tmp%s.ps" % rend)
                    pslist.append("/tmp/tmp%s.pdf" % rend)
            else:
                numofpages = range(engrave_pianoscript_vertical('export',
                    renderpageno,
                    Score,
                    MM,
                    last_pianotick,
                    color_notation_editor,
                    color_editor_canvas,
                    pview,root,
                    BLACK))
                for rend in numofpages:
                    pview.postscript(file=f"tmp{rend}.ps",
                        x=rend * (Score['properties']['page-width'] * MM),
                        y=10000, 
                        width=Score['properties']['page-width'] * MM,
                        height=Score['properties']['page-height'] * MM, 
                        rotate=False,
                        fontmap='-*-Courier-Bold-R-Normal--*-120-*')
                    process = subprocess.Popen(
                        f'''pstopdf tmp{rend}.ps''', shell=True)
                    process.wait()
                    os.remove(f"tmp{rend}.ps")
                    pslist.append(f"tmp{rend}.pdf")
            cmd = 'pdfunite '
            for i in range(len(pslist)):
                cmd += pslist[i] + ' '
            cmd += '"%s"' % f.name
            process = subprocess.Popen(cmd, shell=True)
            process.wait()
            # remove temporary pdf page files
            for rend in numofpages:
                os.remove(f"tmp{rend}.pdf")
(there seems to be a bug in the code coloring in this site, I see parts of the code in green like a string which is not in my text editor)
Gribouillis likes this post
Reply


Messages In This Thread
RE: Universal(MACWINLIN) canvas pdf export - by philipbergwerf - Jul-27-2023, 04:37 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020