Search code examples
pythondjangodatabaseweb-applicationswebcam

capture image and save it to database with django


I am trying to make a web app with django in which it clicks an image from the camera and saves the image to a database. How can that be implemented? if there is a source code available, kindly share a link to it. thank you


Solution

  • I came here hoping to find an answer; there not being one, I hereby offer mine ...

    The trick is to encode the image and save it as a TextField.

    The solution I provide is bit clunky in the way the images are read every time select_image.html is loaded, but I did that because my requirement is a bit more complex and this does the job. I assume you know how to get the image from the camera (which is equivalent to my reading it from file).

    There are two templates, select_image.html and display_image.html. When select_image.html is called for the first time it reads .png images from file and saves the images to the database. When an image is selected it is retrieved from the database and displayed in display_image.html.

    select_image.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Select Image</title>
    </head>
    <body>
        <h1>Select Image</h1>
    
        {% block content %}
            <ul>
                {% for image in images %}
                    <li><a href="display-image/{{ image }}">{{ image }}</a></li>
                {% endfor %}
            </ul>
        {% endblock %}
    </body>
    </html>
    

    display_image.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Display Image</title>
    </head>
    <body>
        <h1>Display Image</h1>
    
        {% block content %}
            <img id="image" src="{{ image }}" alt="image">
        {% endblock %}
        <p></p>
        <a href="/users/images">Images</a>
    </body>
    </html>
    

    models.py

    class Image(models.Model):
        name = models.CharField(max_length=25, null= False, blank=False, default='image_name', unique=True)
        image = models.TextField()
    

    urls.py

    urlpatterns = [
        path('images', views.Images.as_view(), name='images'),
        path('display-image/<str:image_name>/', views.DisplayImage.as_view(), name='display-image'),
    ]
    

    views.py

    from PIL import Image as PilImage
    import io
    import base64
    import os
    from .models import Image
    
    class Images(View):
        url = "images/select_image.html"
    
        def get(self, request):
            dir = <image file directory>
            image_names = ['red', 'green', 'blue']
            for image_name in image_names:
                base_path = os.sep.join([dir, image_name])
                path = '.'.join([base_path, 'png'])
                pil_image = PilImage.open(path)
                encoded_image = self._encode_image(pil_image)
                Image.objects.get_or_create(name=image_name, image=encoded_image)
            context = {'images': image_names}
            return render(request, self.url, context)
    
        @staticmethod
        def _encode_image(image):
            """Return image encoded to base64 from a PIL.Image.Image."""
            io_buffer = io.BytesIO()
            image.save(io_buffer, format='PNG')
            saved_image = io_buffer.getvalue()
            encoded_image = ''.join(['data:image/jpg;base64,', base64.b64encode(saved_image).decode()])
            return encoded_image
    
    class DisplayImage(View):
        url = "images/display_image.html"
    
        def get(self, request, image_name):
            image = get_object_or_404(Image, name=image_name)
            context = {'image': image.image}
            return render(request, self.url, context)