I can't read the image from pdf (photos not shown on pdf)

Hi people I hope all here,are doing well;
i have a question and i need some help .
The images are not showing in my PDF files. I have the pictures
added in binary file format. Here is an overview:

  • Python Code:
    photo = fields.Binary("Photo")

  • Code XML:
    <field name="my_photo" widget="image"/>

  • In the report:

<table:table-cell table:style-name="Table3.M_1" office:value-type="string">
<text:p text:style-name="P129"><draw:frame draw:style-name="fr2" draw:name="Bild3" text:anchor-type="paragraph" svg:x="0.071cm" svg:y="0.566cm" svg:width="4.14cm" svg:height="1.8cm" draw:z-index="6">
<draw:image loext:mime-type="image/png">
<office:binary-data>
<text:placeholder text:placeholder-type="text">&lt;myphoto&gt;</text:placeholder>
</office:binary-data>
</draw:image>
</draw:frame></text:p>
</table:table-cell>
  • The classes are:
    class PrintCertificat(ModelView):
        __name__ = 'party.print_certificat'
        from_date = fields.Date('From Date', required=True)
        to_date = fields.Date('To Date', required=True)
        company = fields.Many2One('party.certificat', 'Company', required=True)//party.certificat  is the class that does the
            Contains image.
        posted = fields.Boolean('Posted Move', help='Show only posted move')

        @staticmethod
        def default_from_date():
            Date = Pool().get('ir.date')
            return datetime.date(Date.today().year, 1, 1)

        @staticmethod
        def default_to_date():
            Date = Pool().get('ir.date')
            return Date.today()
        @staticmethod
        def default_to_date():
            Date = Pool().get('ir.date')
            return Date.today()

        @staticmethod
        def default_company():
            return Transaction().context.get('company')

        @staticmethod
        def default_posted():
            return False

    class PrintCertificat(Wizard):

      __name__ = 'party.print_certificat_'
        start = StateView('party.print_certificat',
            'module_name.print_certificat_view_form', [
                Button('Cancel', 'end', 'tryton-cancel'),
                Button('Print', 'print_', 'tryton-print', default=True),
                ])
        print_ = StateReport('module_name.party.certificat_report')
        def do_print_(self, action):
            data = {
                'company': self.start.company.id,
                }
            return action, data

    class CertificatReport(Report):
        __name__ = 'module_name.party.certificat_report'
        @classmethod
        def _get_records(cls, ids, model, data):
            Move = Pool().get('party.certificat')
            clause = [
                ]
        @classmethod
        def get_context(cls, records, data):
            report_context['myphoto'] = company.photo
            return report_context

            indx = 0
            report_context = super(CertificatReport, cls).get_context(records, data)

            Company = Pool().get('party.certificat') 

            company = Company(data['company'])

            report_context['company'] = company

To include image in relatorio from a statement, it is the name of the frame that must contain the expression see https://relatorio.readthedocs.io/en/latest/indepthexample.html?highlight=frame#a-not-so-real-example

thank you for your response but i did’nt understand what’s wrong in my code to correct it !
what do you mean by name of the frame!

It is the attribute name of the tag frame.

i have tried much time trying but i did’nt succeed ,
and lastly i have inserted the expression
draw:name="image: bomitem.certification_module.image, "image/jpg" " on the attribute name
on the frame like this :

    <table:table-cell table:style-name="Table3.M_1" office:value-type="string">
    <text:p text:style-name="P129"><draw:frame draw:style-name="fr2" draw:name="image: bomitem.certification_module.image, “image/jpg" " text:anchor-type="paragraph" svg:x="0.071cm" svg:y="0.566cm" svg:width="4.14cm" svg:height="1.8cm" draw:z-index="6">
    <draw:image loext:mime-type="image/png">
          <office:binary-data>
    <text:placeholder text:placeholder-type="text">&lt;myphoto&gt;</text:placeholder>
      </office:binary-data>
         </draw:image>
        </draw:frame></text:p>

     </table:table-cell>

i want just to understand a thing from you to keep trying

from the link that u mensionned to me , i found that i should add an expression in the frame
and me i added it like this am i true

draw:name="image: bomitem.certification_module.image, “image/jpg" "
because when i made this expression the frame , give me an error :

    Traceback (most recent call last):
      File "/site-packages/relatorio/templates/opendocument.py", line 814, in get_zip_file
        return zipfile.ZipFile(source)
      File "/zipfile.py", line 1222, in __init__
        self._RealGetContents()
      File "/zipfile.py", line 1289, in _RealGetContents
        raise BadZipFile("File is not a zip file")
    zipfile.BadZipFile: File is not a zip file

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/trytond/wsgi.py", line 104, in dispatch_request
        return endpoint(request, **request.view_args)
      File "/trytond/protocols/dispatcher.py", line 48, in rpc
        request, database_name, *request.rpc_params)
      File "/trytond/wsgi.py", line 72, in auth_required
        return wrapped(*args, **kwargs)
      File "/trytond/protocols/wrappers.py", line 131, in wrapper
        return func(request, pool, *args, **kwargs)
      File "/trytond/protocols/dispatcher.py", line 197, in _dispatch
        result = rpc.result(meth(*c_args, **c_kwargs))
      File "/trytond/report/report.py", line 191, in execute
        oext, content = cls._execute(records, data, action_report)
      File "/trytond/report/report.py", line 217, in _execute
        return cls.convert(action, cls.render(action, report_context))
      File "/trytond/report/report.py", line 317, in render
        data = rel_report(**report_context).render()
      File "/site-packages/relatorio/reporting.py", line 121, in __call__
        template = self.tmpl_loader.load(self.fpath, self.mimetype)
      File "/site-packages/relatorio/reporting.py", line 81, in load
        path, cls=cls, relative_to=relative_to)
      File "/site-packages/genshi/template/loader.py", line 238, in load
        filename, encoding=encoding)
      File "/site-packages/genshi/template/loader.py", line 276, in _instantiate
        allow_exec=self.allow_exec)
      File "/site-packages/relatorio/templates/opendocument.py", line 237, in __init__
        encoding, lookup, allow_exec)
      File "/site-packages/genshi/template/markup.py", line 67, in __init__
        allow_exec=allow_exec)
      File "/site-packages/genshi/template/base.py", line 421, in __init__
        self._stream = self._parse(source, encoding)
      File "/site-packages/relatorio/templates/opendocument.py", line 258, in _parse
        zf = get_zip_file(source)
      File "/site-packages/relatorio/templates/opendocument.py", line 819, in get_zip_file
        return zipfile.ZipFile(fod2od(source))
      File "/site-packages/relatorio/templates/opendocument.py", line 826, in fod2od
        fodt_tree = lxml.etree.parse(source)
      File "src/lxml/etree.pyx", line 3521, in lxml.etree.parse
      File "src/lxml/parser.pxi", line 1859, in lxml.etree._parseDocument
      File "src/lxml/parser.pxi", line 1885, in lxml.etree._parseDocumentFromURL
      File "src/lxml/parser.pxi", line 1789, in lxml.etree._parseDocFromFile
      File "src/lxml/parser.pxi", line 1177, in lxml.etree._BaseParser._parseDocFromFile
      File "src/lxml/parser.pxi", line 615, in lxml.etree._ParserContext._handleParseResultDoc
      File "src/lxml/parser.pxi", line 725, in lxml.etree._handleParseResult
      File "src/lxml/parser.pxi", line 654, in lxml.etree._raiseParseError
      File "/tmp/trytond_ol97cl97.odt", line 468
    lxml.etree.XMLSyntaxError: attributes construct error, line 468, column 132

Before you are going to modify the XML file, just use LibreOffice to make it work. As an example see https://groups.google.com/g/tryton-dev/c/4N0l2-im2jc In that thread I’m talking about a QR-code adding to a report, but the base is the same:

  • draw a frame in LibreOffice (Insert -> Frame -> Frame)
  • make sure it’s anchored to a paragraph (tab ‘Type’, header ‘Anchor’)
  • enter as name image: (<your_record.photo>, "image/png") (tab ‘Options’)
  • keep the rest as-is

If that’s working you can make adjustments and then look at the XML how that looks like.

is theire examples about how to write the expression on tag frame or examples step by step how to do to make the images shown without any problem!

You say in tab “Options” mention “your_record .photo” ,
so which record you mean here, did u mean the name o the module or the name of the class where i will display my image!

It’s a bit hard to get an idea how your report looks like, but your report has something like for record in records at the top right? So you can loop over the records. I assume that the photo field is in a record.
So change the <your_record.photo> to record.photo so it will look like:

image: (record.photo, "image/png") 
Again, I assume that the the field is in the record. If you also printing the dates with `record.from_date` and `record.to_date` then you should use `record.photo`. If you use e.g. `rec.from_date` , then you should use `rec.photo`

If it still doesn’t work, try

image: record.photo 

If this all doesn’t work, let me know I can dig a bit deeper into this.
The last one should work. I use the same code in one of my reports

I always use LibreOffice first to get the layout kind of right. Then I save the file as a fodt which is bigger in size then odt but you can easily edit the file with your favorite texteditor. I mostly do the last thing to clean up extra tags between text to get translations working and to fine-tune some distances which are hard to do with a GUI.

this way of writing the expression is it correct !!
<draw:frame draw:style-name="fr2" draw:Options="image: record.photo " text:anchor-type="paragraph" >

there is an error shown when i made the expression like that .
the error was
genshi.template.eval.UndefinedError: None has no member named “photo”

Out of curiosity, Why are you not using LibreOffice or OpenOffice to make it work?

Which other fields are you printing in your report and how did you name them?

Hi again ;
the report printed with the extension .odt, i opened the report with “Libre office Writer”" , i found the area where it should be the image empty with the word “read error”

-See this photo


on the left side ,must be shown an image ,the field named and defined on python et on xml "photo"
on the right side ,must be shown another image must be uploded ,the field named and defined on python et on xml "test_photo"

i defined those two fields on python like that :

photo = fields.Binary("Photo")
test_photo =fields.Function(fields.Binary("Plan",required=True), 'on_change_Plan')

Ok, I tried it myself. I just edited the module sale (because it has already a report etc.) and added a new field to the sale order class:

photo = fields.Binary("Photo")

I also changed the form view so I can add an image

<label name="photo"/>
<field name="photo"/>

Then I changed the default sale template (sale.fodt in the module directory) with LibreOffice Writer and added a new frame just below the sale details on the second page. The frame is anchored at the paragraph and as Name I added

image: (sale.photo, 'image/png')

Then I updated the server so the field is added to the database and added an image to a sale and printed that sale order. It worked fine.

As you can see I used sale.photo here because when you look at the report template you also see sale.state or sale.full_number. Those placeholders are replaced with data from Tryton and represent a field on the sale order.

In short, my suggestion about the ‘Name’ in a post above is wrong.

I suggest you to take a look at the sale template (with LibreOffice Writer). As you can see on the first page there is a <for each="sale in records">. You have to have something similar.

1 Like

HI again
I do no what’s wrong one more time
i made the code of the photo from what i understand from you like this :

i was put "company"
draw:name="image: (company.photo, 'image/png')"
because in the class python of creating this report , i was made the class like this :

    class CertificateReport(Report):
        __name__ = 'ModuleCertficates.party.certificate_report'


      
        @classmethod
        def _get_records(cls, ids, model, data):
            Move = Pool().get('party.certicate')

            clause = [

                ]
     

        @classmethod
        def get_context(cls, records, data):
            indx = 0
            report_context = super(CertificateReport, cls).get_context(records, data)

            Company = Pool().get('party.certicate')

            company = Company(data['company'])

            report_context['photo'] = company.photo

but after upgrading , there was error :

      Traceback (most recent call last):
      File "/trytond/wsgi.py", line 104, in dispatch_request
        return endpoint(request, **request.view_args)
      File "/trytond/protocols/dispatcher.py", line 48, in rpc
        request, database_name, *request.rpc_params)
      File "/trytond/wsgi.py", line 72, in auth_required
        return wrapped(*args, **kwargs)
      File "/trytond/protocols/wrappers.py", line 131, in wrapper
        return func(request, pool, *args, **kwargs)
      File "/trytond/protocols/dispatcher.py", line 197, in _dispatch
        result = rpc.result(meth(*c_args, **c_kwargs))
      File "/trytond/report/report.py", line 191, in execute
        oext, content = cls._execute(records, data, action_report)
      File "/trytond/report/report.py", line 217, in _execute
        return cls.convert(action, cls.render(action, report_context))
      File "/trytond/report/report.py", line 317, in render
        data = rel_report(**report_context).render()
      File "/site-packages/relatorio/templates/base.py", line 34, in render
        return self.serializer(self.events)
      File "/site-packages/relatorio/templates/opendocument.py", line 982, in __call__
        for kind, data, pos in stream:
      File "/site-packages/genshi/core.py", line 291, in _ensure
        for event in stream:
      File "/site-packages/genshi/filters/i18n.py", line 688, in __call__
        for kind, data, pos in stream:
      File "/site-packages/genshi/template/base.py", line 641, in _include
        for event in stream:
      File "/site-packages/genshi/template/markup.py", line 326, in _match
        for event in stream:
      File "/site-packages/genshi/template/base.py", line 581, in _flatten
        for kind, data, pos in stream:
      File "/site-packages/genshi/template/directives.py", line 171, in _generate
        attrs = _eval_expr(self.expr, ctxt, vars)
      File "/site-packages/genshi/template/base.py", line 291, in _eval_expr
        retval = expr.evaluate(ctxt)
      File "/site-packages/genshi/template/eval.py", line 160, in evaluate
        return eval(self.code, _globals, {'__data__': data})
      File "<string>", line 534, in <Expression '__relatorio_make_href(__relatorio_get_cache(139912478557128))'>
      File "/site-packages/relatorio/templates/opendocument.py", line 124, in __call__
        bitstream = bitstream.generate(**self.context).render()
    AttributeError: 'NoneType' object has no attribute 'generate'

The problem is that company.photo is empty.
Relatorio does not yet support empty image: Bug 62: Support empty image - Relatorio tracker

1 Like

Yeah it was my fault i forgot uploading the image in the field , Thank you for everyone here helped me.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.