Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reportlab's Code128 Barcode as HTML Image Tag with Data URI Scheme in Python

I need to create an Code128 Barcodes with Python/Django which have to be embeded in HTML document.

I don't want to make any temporary (or cache) files on the disk. That's why I want to embed them as Data URI Scheme.

The result have to be something like this:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">

Can you recommend me an easy way to do this?

Now I use ReportLab to create such a barcodes and embed them in PDF files, but I don't know how to export them as Data URI Scheme. If this is the recommended way to do this.

like image 902
Julian Popov Avatar asked Nov 12 '12 14:11

Julian Popov


3 Answers

This is my own solution:

from base64 import b64encode
from reportlab.lib import units
from reportlab.graphics import renderPM
from reportlab.graphics.barcode import createBarcodeDrawing
from reportlab.graphics.shapes import Drawing

def get_barcode(value, width, barWidth = 0.05 * units.inch, fontSize = 30, humanReadable = True):

    barcode = createBarcodeDrawing('Code128', value = value, barWidth = barWidth, fontSize = fontSize, humanReadable = humanReadable)

    drawing_width = width
    barcode_scale = drawing_width / barcode.width
    drawing_height = barcode.height * barcode_scale

    drawing = Drawing(drawing_width, drawing_height)
    drawing.scale(barcode_scale, barcode_scale)
    drawing.add(barcode, name='barcode')

    return drawing

def get_image():

    barcode = get_barcode(value = '01234567890', width = 600)
    data = b64encode(renderPM.drawToString(barcode, fmt = 'PNG'))
    print '<img src="data:image/png;base64,{0}">'.format(data)

And also you can get barcode rotated by 90°:

def get_barcode_rotated(value, width, barWidth = 0.05 * units.inch, fontSize = 30, humanReadable = True):

    barcode = createBarcodeDrawing('Code128', value = value, barWidth = barWidth, fontSize = fontSize, humanReadable = humanReadable)

    drawing_width = width
    barcode_scale = drawing_width / barcode.width
    drawing_height = barcode.height * barcode_scale

    drawing = Drawing(drawing_width, drawing_height)
    drawing.scale(barcode_scale, barcode_scale)
    drawing.add(barcode, name='barcode')

    drawing_rotated = Drawing(drawing_height, drawing_width)
    drawing_rotated.rotate(90)
    drawing_rotated.translate(0, -drawing_height)
    drawing_rotated.add(drawing, name='drawing')

    return drawing_rotated

Here is an example result:

http://pastehtml.com/view/ci7qei4k1.html

like image 194
Julian Popov Avatar answered Nov 13 '22 19:11

Julian Popov


This should do the trick. I used the Code128 python module to generate the barcodes.

code

from Code128 import Code128
from base64 import b64encode

val = "9782212110708"
Code128().getImage(val, path="./")
data = b64encode(open(val + '.png').read())
print '<img src="data:image/png;base64,{0}">'.format(data)

output

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIMAAAAyAQAAAABXcFUb
AAAAjklEQVR4nGP8r2v6J/ihYotFKrs5qx9H2TwmBnQwKjIqMnRFGP+jCTzErkvS6IR80Yu5iScU
GBgYGFgYGP4b3j6t9Xn+ZG4jA6gIAxtDos26ROHFcF2M+32/XPjLwPCX8QLMnAOfXyz4xcDA8B+m
63/djHUCHxkYfkEt+///v8zHJg6GBpbi4/L///9/AADHAS8/nZ4QEQAAAABJRU5ErkJggg==">

UPDATE

there was a nice suggestion in the comments to modify the Code128 module so that it doesn't have to save the image to the filesystem. You can change Code128 so that it returns you the image object instead of saving it to a file. You would only need to change one line of code to achieve this. Change line 162 from:

im.save(path+value+"."+lower(extension), upper(extension))

to:

return im
like image 38
Marwan Alsabbagh Avatar answered Nov 13 '22 20:11

Marwan Alsabbagh


Have you tried assembling the barcode on the fly with each symbol represented with its own image data? Here's an example:

<img alt="105,{Start C}" title="105,{Start C}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/ACxgALsAjajKmzkAAAAASUVORK5CYII=" width="30" height="60"><img alt=" 00,A:{space},B:{space}" title=" 00,A:{space},B:{space}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/ACZgAK8Ah/KrWu0AAAAASUVORK5CYII=" width="30" height="60"><img alt=" 98,A:{Escape B},B:{Escape A}" title=" 98,A:{Escape B},B:{Escape A}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/AAugALkArBSbglwAAAAASUVORK5CYII=" width="30" height="60"><img alt=" 21,A:{5},B:{5}" title=" 21,A:{5},B:{5}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/ACNgAKkAhD/i5lYAAAAASUVORK5CYII=" width="30" height="60"><img alt=" 14,A:{.},B:{.}" title=" 14,A:{.},B:{.}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/AGYgAO8Ah9WahQgAAAAASUVORK5CYII=" width="30" height="60"><img alt=" 00,A:{space},B:{space}" title=" 00,A:{space},B:{space}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/ACZgAK8Ah/KrWu0AAAAASUVORK5CYII=" width="30" height="60"><img alt=" 14,A:{.},B:{.}" title=" 14,A:{.},B:{.}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/AGYgAO8Ah9WahQgAAAAASUVORK5CYII=" width="30" height="60"><img alt=" 64,A:{NUL},B:{}" title=" 64,A:{NUL},B:{}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/AF5gAR8Av0A69KoAAAAASUVORK5CYII=" width="30" height="60"><img alt=" 95,A:{US},B:{DEL}" title=" 95,A:{US},B:{DEL}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/AELgAWcBIz+IUR4AAAAASUVORK5CYII=" width="30" height="60"><img alt=" 07,A:{'},B:{'}" title=" 07,A:{'},B:{'}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/AGdgATEAyJ/9LboAAAAASUVORK5CYII=" width="30" height="60"><img alt=" 74,A:{LF},B:{j}" title=" 74,A:{LF},B:{j}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/AHmgAZUBGuCD0Y8AAAAASUVORK5CYII=" width="30" height="60"><img alt="101,A:{FNC 4},B:{Switch A},C:{Switch A}" title="101,A:{FNC 4},B:{Switch A},C:{Switch A}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/ABQgAEsANWhuDt4AAAAASUVORK5CYII=" width="30" height="60"><img alt=" 25,A:{9},B:{9}" title=" 25,A:{9},B:{9}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/ABpgAJcAex9glyQAAAAASUVORK5CYII=" width="30" height="60"><img alt=" 12,A:{,},B:{,}" title=" 12,A:{,},B:{,}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAABAQMAAAAy+cYDAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/AExgAPsArevKOWsAAAAASUVORK5CYII=" width="30" height="60"><img alt="106,{Stop}"title="106,{Stop}"src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAABAQMAAAA/57ZEAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAADklEQVQIHQEDAPz/ADigARMA2dpJzT8AAAAASUVORK5CYII=" width="30" height="60">
009821140014649507749

This represents the same barcode as your example, but requires no intermediate graphics and takes up about a third of the space. The data used to comprise the image can be accessed from an array and used to populate the target HTML with Javascript or another client or server-side application.

You can find a complete list of Code 128 symbols at http://notionovus.com/blog/code-128-barcode/

I am not sure about rotation. I haven't tried that yet.

like image 21
Brian Anderson Avatar answered Nov 13 '22 20:11

Brian Anderson