1

I am calling a django rest framework get api to create a barcode. Its working fine when I tried to save it as an image.

@api_view(['GET'])
def mybarcode(request):
    from elaphe import barcode

        code = barcode('datamatrix', "sampletext",
                       encoding='utf-8', scale=2,
                       options=dict(columns=24, rows=24),
                       margin=2, data_mode='50bits')
        code.save("mybarcode.jpg")
        return Response({'status': True})

This working fine when I call this API as "http://127.0.0.1:9999/api/v1/testbarcode". An image will be created with the name "mybarcode.jpg" and the api return its status as True.

But I would like to return the image as the result of this api call. Because I have to include this in a image tag.

<img src='http://127.0.0.1:9999/api/v1/testbarcode' />

Is there any way to do this?

4
  • Can you post model? Commented May 29, 2018 at 11:10
  • not related to any db model. Just a GET api. Commented May 29, 2018 at 11:25
  • I think not. You can only return the storage path of the saved image. You can use Storage servers like AWS. Commented May 29, 2018 at 11:31
  • i think you need to store it at some place(storage), it is easier to store it in DB and return the image path with serializers, or if you don't want it then you need to convert that image to base64 in string format and return that string. Commented May 29, 2018 at 11:47

4 Answers 4

6

I used this to return a member's QR code:

@staticmethod
def qr_code(request, member_id):
    m = Member.objects.get(id=member_id)
    response = HttpResponse(m.generate_qrcode())
    response['Content-Type'] = "image/png"
    response['Cache-Control'] = "max-age=0"
    return response

Calling this on the Member class:

def generate_qrcode(self):
    qr = qrcode.QRCode(
        version=2,
        error_correction=qrcode.constants.ERROR_CORRECT_H,
        box_size=4,
        border=0,
    )
    qr.add_data(self.formatted_id())
    qr.make(fit=True)

    img = qr.make_image()

    buffer = BytesIO()
    img.save(buffer)

    return buffer.getbuffer()

This way nothing touches the disk, although I think it will hog memory at higher concurrencies.

Sign up to request clarification or add additional context in comments.

Comments

3

Returning an image/file in Django view should be avoided. Web-servers NGINX/Apache are good at handling them.

Save the image in a storage, like local disk, AWS S3 or other cloud storage. And then render image depending on where it stored.

In case of local storage it can be delivered using web server. Images stored in AWS S3 can be served via AWS CDN Cloudfront.

3 Comments

Do you mean that in production it is better to send https://serverpath/media/user/123/profile.png instead of having an API like https://serverpath/api/user/123/profile that returns the image?
This answer is not really relevant to the question - you wouldn't generate every possible barcode and save in S3. But where this answer is relevant, when you have a specific set of media files, use the Django MEDIA_URL settings. S3 does have public URLs too, which are slightly slower but save on the fairly pricey CloudFront costs.
Why returning an image/file in Django view should be avoided? How do we handle generation of qr or bar code image? For static files, yes you should avoid. The author is not talking about static files. The author question is about dynamic images.
0

for converting image to base64

import base64
def(yourimagefile):
     with open(yourimagefile, "rb") as image_file:
         base64string = base64.b64encode(image_file.read())
         return base64string

hook this module after your image created and change your html for displaying the base64 content

Comments

0

Still too much code. Simplified:

import io
import segno

def generate_qrcode(self):
    buffer = io.BytesIO()
    segno.make(self.formatted_id(), version=2, error='h') \
         .save(buffer, kind='png', scale=4, border=0)
    return buffer.getvalue()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.