Search code examples
pythonfpdf

Insert Base64 image to pdf using pyfpdf


I'm using pyfpdf in python to generate pdf files. I have a Base64 which I want to insert into a pdf file without having to save it as an image in my file system. But the pyfpdf image function only accepts file path.

fpdf.image(name, x = None, y = None, w = 0, h = 0, type = '', link = '')

Is there a way (hack) to directly insert base64 or buffered image from memory, without having to save into the file system beforehand? I even checked their source code on github and couldn't figure.

link : https://github.com/reingart/pyfpdf/tree/master/fpdf


Solution

  • As @pvg mentioned in the comments, overriding load_resource function with your base64 functionality does the trick.

    import base64,io
    
    def load_resource(self, reason, filename):
        if reason == "image":
            if filename.startswith("http://") or filename.startswith("https://"):
                f = BytesIO(urlopen(filename).read())
            elif filename.startswith("data"):
                f = filename.split('base64,')[1]
                f = base64.b64decode(f)
                f = io.BytesIO(f)
            else:
                f = open(filename, "rb")
            return f
        else:
            self.error("Unknown resource loading reason \"%s\"" % reason)
    

    EDIT :

    This is a sample code to insert images into pdf. I commented some instructions in code.

    from fpdf import FPDF
    import os
    import io
    import base64
    
    
    class PDF(FPDF):
    
        def load_resource(self, reason, filename):
            if reason == "image":
                if filename.startswith("http://") or filename.startswith("https://"):
                    f = BytesIO(urlopen(filename).read())
                elif filename.startswith("data"):
                    f = filename.split('base64,')[1]
                    f = base64.b64decode(f)
                    f = io.BytesIO(f)
                else:
                    f = open(filename, "rb")
                return f
            else:
                self.error("Unknown resource loading reason \"%s\"" % reason)
    
    
        def sample_pdf(self,img,path):
    
            self.image(img,h=70,w=150,x=30,y=100,type="jpg")
            #make sure you use appropriate image format here jpg/png
            pdf.output(path, 'F')
    
    if __name__ == '__main__':
        img = # pass your base64 image
        # you can find sample base64 here : https://pastebin.com/CaZJ7n6s
    
        pdf = PDF()
        pdf.add_page()
        pdf_path = # give path to where you want to save pdf
        pdf.sample_pdf(img,pdf_path)