0

I am doing a Django project that needs to receive an image and store it into the database as a TextField. To accomplish that I am doing something similar to this:

In my models.py:

class Template(models.Model):
    image = models.TextField(null=True, blank=True)

The equivalent code is:

with open('logo.png', 'rb') as file:
    image = str(file.read())

Template.objects.create(id=1, image=image)

Later, when I need to get back the file and convert it to base64 to insert in an HTML file, I am doing the following:

import base64
from django.template import Template as DjangoTemplate
from django.template import Context

from weasyprint import HTML

from .models import Template

template = Template.objects.get(id=1)
data = {'logo': base64.b64encode(str.encode(template.image)).decode('utf-8')}

html_template = DjangoTemplate(template.html_code)
html_content = html_template.render(Context(data)))
file = open('my_file.pdf', 'wb')
file.write(HTML(string=html_content, encoding='utf8').write_pdf())
file.close()

But the problem is that the image is not showing in the pdf file. I've also tried to copy the decoded data and open it with another site, but I got a broken file.

How can I fix my code to convert the image properly?

Matheus Sant'ana
  • 563
  • 2
  • 6
  • 23
  • I'm not sure if that helps but I personally would store the data as base64 string in your model. Something like this https://stackoverflow.com/questions/4915397/django-blob-model-field. – Damien LEFEVRE Jun 05 '20 at 18:26
  • That actually works, but I saw that storing a base64 is not a good practice and it cost more in terms of storage. https://stackoverflow.com/questions/11402329/what-is-the-effect-of-encoding-an-image-in-base64 – Matheus Sant'ana Jun 05 '20 at 18:30
  • Yes it'll be bigger. But if you try to insert binary data into a text field, the binary data will be reinterpreted to the sting encoding used. If utf-8 for example, depending on the value of the bytes, 1 to 4 bytes will be converted to a character. https://en.m.wikipedia.org/wiki/UTF-8#:~:text=UTF-8%20(8-bit,Ken%20Thompson%20and%20Rob%20Pike. – Damien LEFEVRE Jun 05 '20 at 19:11
  • What do you mean by that? Is that the reason I cannot convert the file to a base64 later on? – Matheus Sant'ana Jun 05 '20 at 19:26
  • That could be the reason. Check the size of your input image binary buffer and the template.image output. They are possibly of different size. That would be because of the string encoding. – Damien LEFEVRE Jun 05 '20 at 19:49

1 Answers1

0

As far as i see, you are opening your image with write access.

with open('logo.png', 'wb') as file:
    image = str(file.read())

try to use the 'open()-function' with 'rb'.

See Python Docu Input and Output - "mode can be 'r' when the file will only be read, 'w' for only writing (an existing file with the same name will be erased)..."

Try:

with open('logo.png', 'rb') as file:
    image = str(file.read())