About Saving PDF Previews

PDF previews as JPEG or PNG images can be saved using the pdf2image library:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from django.db import models
from django.utils.translation import gettext_lazy as _

class PDFDocument(models.Model):
    pdf = models.FileField(_("PDF Document"))
    thumbnail = models.ImageField(
        _("Thumbnail"),
        blank=True,
        null=True,
    )
    def __str__(self):
        return self.pdf.name

    def save_thumbnail(self, commit=True):
        from io import BytesIO
        from django.core.files.storage import default_storage
        from django.core.files.base import ContentFile
        from pdf2image import convert_from_bytes

        pdf_bytes = default_storage.open(self.pdf.name).read()
        images = convert_from_bytes(
            pdf_file=pdf_bytes, 
            first_page=1,
            last_page=1,
        )
        image = images[0]
        byte_array = BytesIO()
        image.save(byte_array, format="JPEG")

        image_file_name = self.pdf.name[:-4] + ".jpg"
        path = default_storage.save(
            image_file_name, 
            ContentFile(byte_array.getvalue()),
        )
        self.thumbnail = path
        if commit:
            self.save(update_fields=["thumbnail"]

    def save(self, *args, **kwargs):
        if not self.thumbnail:
            self.save_thumbnail(commit=False)
        super().save(*args, **kwargs)

Two notes:

  • You will need poppler package in your OS to use pdf2image.
  • You can call the save_thumbnail() method from a background task to improve performance.

Tips and Tricks Programming Development Django 4.2 Django 3.2 Django 2.2 Python 3 Pillow PDF