Рубрики
Без рубрики

Создание QR-кодов с Python

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

На днях я подумал, что было бы интересно создать небольшую программу, которая может генерировать QR-коды и показать их на экране с WxPython. Конечно, я хотел сделать все это с Python, поэтому после небольшого взгляда я пришел через 3 кандидата:

Я попробовал Python-QRCode и Pyqrnative, поскольку они работали на Windows, а также Mac и Linux. Им также не потребовалось ничего, кроме библиотеки визуализации Python. Проект PYQRCode требует нескольких других предпосылок и не работал на Windows, поэтому я не хотел связываться с этим. Я оказался предприниматься некоторым старым кодом на основе моего приложения Viewer Photo и немного изменено, чтобы сделать этот просмотрщик QR-кода. Если я пробудил ваш интерес, то читай!

Начиная

Как я отметил в начале, вам понадобится Библиотека визуализации Python Отказ Мы будем использовать wxpython Для партии GUI, так что вам тоже понадобится. И вы захотите скачать python-qrcode и pyqrnative. Основное отличие, которое я нашел, заключается в том, что Python-QRCode намного быстрее создает изображения, и он генерирует тип, который вы, вероятно, видели больше всего. По какой-то причине PYQRNATION займет намного больше дольше, и он создает много более плотного QR-кода. Могут быть варианты для обоих этих проектов, которые позволяют создавать различные виды кодов, но документация для любого проекта является ABYSMAL. Я закончил использовать IDE источник и Wingware, чтобы пройти код больше всего на свете.

Генерация QR-кодов

В любом случае, как только у вас есть все предварительные условия, вы можете запустить следующий код и посмотреть, какой Python может сделать:

import os
import wx

try:
    import qrcode
except ImportError:
    qrcode = None
    
try:
    import PyQRNative
except ImportError:
    PyQRNative = None

########################################################################
class QRPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent)
        self.photo_max_size = 240
        sp = wx.StandardPaths.Get()
        self.defaultLocation = sp.GetDocumentsDir()
        
        img = wx.EmptyImage(240,240)
        self.imageCtrl = wx.StaticBitmap(self, wx.ID_ANY,
                                         wx.BitmapFromImage(img))
 
        qrDataLbl = wx.StaticText(self, label="Text to turn into QR Code:")
        self.qrDataTxt = wx.TextCtrl(self, value="http://www.mousevspython.com", size=(200,-1))
        instructions = "Name QR image file"
        instructLbl = wx.StaticText(self, label=instructions)
        self.qrPhotoTxt = wx.TextCtrl(self, size=(200,-1))
        browseBtn = wx.Button(self, label='Change Save Location')
        browseBtn.Bind(wx.EVT_BUTTON, self.onBrowse)
        defLbl = "Default save location: " + self.defaultLocation
        self.defaultLocationLbl = wx.StaticText(self, label=defLbl)
        
        qrcodeBtn = wx.Button(self, label="Create QR with qrcode")
        qrcodeBtn.Bind(wx.EVT_BUTTON, self.onUseQrcode)
        pyQRNativeBtn = wx.Button(self, label="Create QR with PyQRNative")
        pyQRNativeBtn.Bind(wx.EVT_BUTTON, self.onUsePyQR)
        
        # Create sizer
        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        qrDataSizer = wx.BoxSizer(wx.HORIZONTAL)
        locationSizer = wx.BoxSizer(wx.HORIZONTAL)
        qrBtnSizer = wx.BoxSizer(wx.VERTICAL)
 
        qrDataSizer.Add(qrDataLbl, 0, wx.ALL, 5)
        qrDataSizer.Add(self.qrDataTxt, 1, wx.ALL|wx.EXPAND, 5)
        self.mainSizer.Add(wx.StaticLine(self, wx.ID_ANY),
                           0, wx.ALL|wx.EXPAND, 5)
        self.mainSizer.Add(qrDataSizer, 0, wx.EXPAND)
        self.mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5)
        locationSizer.Add(instructLbl, 0, wx.ALL, 5)
        locationSizer.Add(self.qrPhotoTxt, 0, wx.ALL, 5)
        locationSizer.Add(browseBtn, 0, wx.ALL, 5)
        self.mainSizer.Add(locationSizer, 0, wx.ALL, 5)
        self.mainSizer.Add(self.defaultLocationLbl, 0, wx.ALL, 5)
        
        qrBtnSizer.Add(qrcodeBtn, 0, wx.ALL, 5)
        qrBtnSizer.Add(pyQRNativeBtn, 0, wx.ALL, 5)
        self.mainSizer.Add(qrBtnSizer, 0, wx.ALL|wx.CENTER, 10)
 
        self.SetSizer(self.mainSizer)
        self.Layout()
        
    #----------------------------------------------------------------------
    def onBrowse(self, event):
        """"""
        dlg = wx.DirDialog(self, "Choose a directory:",
                           style=wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            self.defaultLocation = path
            self.defaultLocationLbl.SetLabel("Save location: %s" % path)
        dlg.Destroy()
        
    #----------------------------------------------------------------------
    def onUseQrcode(self, event):
        """
        https://github.com/lincolnloop/python-qrcode
        """
        qr = qrcode.QRCode(version=1, box_size=10, border=4)
        qr.add_data(self.qrDataTxt.GetValue())
        qr.make(fit=True)
        x = qr.make_image()
        
        qr_file = os.path.join(self.defaultLocation, self.qrPhotoTxt.GetValue() + ".jpg")
        img_file = open(qr_file, 'wb')
        x.save(img_file, 'JPEG')
        img_file.close()
        self.showQRCode(qr_file)
        
    #----------------------------------------------------------------------
    def onUsePyQR(self, event):
        """
        http://code.google.com/p/pyqrnative/
        """
        qr = PyQRNative.QRCode(20, PyQRNative.QRErrorCorrectLevel.L)
        qr.addData(self.qrDataTxt.GetValue())
        qr.make()
        im = qr.makeImage()
        
        qr_file = os.path.join(self.defaultLocation, self.qrPhotoTxt.GetValue() + ".jpg")
        img_file = open(qr_file, 'wb')
        im.save(img_file, 'JPEG')
        img_file.close()
        self.showQRCode(qr_file)
        
    #----------------------------------------------------------------------
    def showQRCode(self, filepath):
        """"""
        img = wx.Image(filepath, wx.BITMAP_TYPE_ANY)
        # scale the image, preserving the aspect ratio
        W = img.GetWidth()
        H = img.GetHeight()
        if W > H:
            NewW = self.photo_max_size
            NewH = self.photo_max_size * H / W
        else:
            NewH = self.photo_max_size
            NewW = self.photo_max_size * W / H
        img = img.Scale(NewW,NewH)
 
        self.imageCtrl.SetBitmap(wx.BitmapFromImage(img))
        self.Refresh()
    

########################################################################
class QRFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="QR Code Viewer", size=(550,500))
        panel = QRPanel(self)

if __name__ == "__main__":
    app = wx.App(False)
    frame = QRFrame()
    frame.Show()
    app.MainLoop()

Код для изменения и отображения изображения объясняется в предыдущей статье, которую я писал (и связанным с вышеупомянутым), поэтому единственными частями, которые вы, вероятно, не будете заботиться о двух методах создания QR-кодов: Onuseqrcode и onusepyqr Отказ Я просто привел несколько примеров с соответствующих веб-сайтов и немного изменил их, чтобы создать изображения QR-кода. Они очень прямые, но не хорошо документированы, поэтому я не могу сказать вам, что происходит. К сожалению, во время этого письма, код для этих проектов серьезно не хватает в DocStrings, с лишь немногими здесь и там. Тем не менее, я смог генерировать некоторые приличные QR-коды. Следующее было сделано с помощью Python-QRCode:

Как видите, это довольно стандартный код. Следующий создан с pyqrnative и намного плотнее выглядит:

Я попробовал сканирование обоих изображений с помощью сканирования BACKode Carcode Android Cate Phone, и оба QR-кодами были правильно читаются. Поэтому, если вам нужен создание изображений QR-кода для вашего проекта, я надеюсь, что один из этих проектов будет соответствовать вашим потребностям!

Обновление 5/21/2012

Один из моих читателей (Mike Farmer) недавно связался со мной о своих экспериментах с Pyqrnative и сказал мне, что «первый аргумент – это размер контейнера, а вторая – это резервирование/ошибка коррекция». Я догадался, что была вторая, но я не знаю, что делают уровень коррекции ошибок. К счастью, мистер Фермер объяснил мне: Если коррекция ошибок низкая, она не сможет терпеть размазывания или слезы к тегу, не прочитав. Но если вы сочтете уровень ошибки, это, очевидно, получит больше QRCode, но что вы сделали, создают дубликаты данных внутри тега. Поэтому, если тег смазан или разрывается, он все еще может прочитать и восстановить оставшиеся данные. Таким образом, если ваше приложение создает теги, которые могут быть повреждены его мудрым, чтобы составить коррекцию ошибок. Вы также можете сделать классную вещь с этим, как накладные изображения или текст на теге, повторная коррекция ошибок, поэтому данные избыточны, а затем могут терпеть «повреждение». В любом случае, если вы измените первый номер, вы можете расти или уменьшить размер изображения QR-кода. Почему ты бы так поступил? Что ж, тем больше информации вам нужно хранить на изображении, тем больше изображение должно быть. Мистер Фермер придумал какой-то веселый тестовый код, чтобы помочь ему выяснить, каким должен быть минимальный размер QR-код. Я воспроизвожу код ниже:

import PyQRNative

def makeQR(data_string,path,level=1):
    quality={1: PyQRNative.QRErrorCorrectLevel.L,
             2: PyQRNative.QRErrorCorrectLevel.M,
             3: PyQRNative.QRErrorCorrectLevel.Q,
             4: PyQRNative.QRErrorCorrectLevel.H}
    size=3
    while 1:
        try:
            q = PyQRNative.QRCode(size,quality[level])
            q.addData(data_string)
            q.make()
            im=q.makeImage()
            im.save(path,format="png")
            break
        except TypeError:
            size+=1

Исходный код

  • QRCodeViewer.zip