Generated QR-code Textures

This may be more fun than good use for most, but still here it is:
Besides showing how to generate and display QR codes on textures, it also does a bit of PIL magic.

You need pytho-qrcode and python-pil to be installed. I tested it on python3, should work on python2.

from panda3d.core import loadPrcFileData 
loadPrcFileData("", """textures-power-2 none""") # not strictly required but convenient
from panda3d.core import NodePath
from panda3d.core import Texture, CardMaker , Point2
from direct.showbase.ShowBase import ShowBase
import qrcode, PIL 
#python-qrcode and python-pil are required

class App(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        #first create a card to display the qr code on
        cm = CardMaker("QR_card")
        cm.setUvRange(Point2(0, 0), Point2(1, 1))
        cm.setFrame(-1, 1, -1, 1)
        self.qrCard = aspect2d.attachNewNode(cm.generate())
        #generate and set the texture
        self.qrCard.setTexture(self.generateQrTexture("www.panda3d.org"))
        #all done now.
    
    def generateQrTexture(self,text):
        #setup qrcode, see https://pypi.python.org/pypi/qrcode
        qr = qrcode.QRCode(version= 1, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=10, border=4)
        qr.add_data(text)
        qr.make()
        img = qr.make_image() #this generates a PIL image from the qr-code
        img = img.transpose(PIL.Image.FLIP_TOP_BOTTOM) #we need to flip stuff due to different coordinate systems (i guess)
        #create a texture, set it up with the required size, and type
        t = Texture()
        t.setup2dTexture(img.size[0],img.size[1],Texture.T_unsigned_byte ,Texture.F_luminance) #grayscale texture 
        t.makeRamImage().setData(img.convert('L').tobytes()) #the pil image is binary encoded as bytes, we need to convert to propper gray values first.
        t.setMagfilter(Texture.FT_nearest) #disable texture filtering to get crisp qr-codes on the screen
        return t

app = App()
app.run()