Еще недавно QR-коды были актуальны как никогда. Но, тьфу-тьфу, надеюсь, что все осталось позади. Тем не менее, эти коды быстрого доступа довольно удобны и используются повсеместно. Поэтому нелишним будет создать приложение, которое их создает. Ну и добавить туда чуть-чуть функционала. Никакого открытия Америки, все довольно просто и банально.
Что понадобиться?
Понадобиться, несмотря на простоту кода довольно много библиотек. Библиотека qrcode, для создания кода, библиотека path для работы с путями. opencv-python для распознавания картинки с кодом. pyzbar для считывания кодов. И еще нужен будет небольшой модуль, который я нашел и который делает создание кода довольно забавным делом. Об этом будет подробнее ниже. А сейчас, устанавливаем библиотеки:
После чего импортируем в модуль:
Теперь приступим к созданию функций. Я разделил их по функционалу, чтобы не запрашивать слишком много данных у пользователя. Хотя, если по правильному, то следовало бы. Но, для демонстрационного кода, да и в большинстве случаев, размер и качество создаваемы QR достаточно для того, чтобы они считывались телефоном. Создадим функцию qr_standard(). Данная функция создает код с классическими квадратиками. Ничего необычного и нестандартного. Для начала запрашиваем текст, который нужно закодировать. Это может быть ссылка на ресурс или просто какое-либо приветствие.
Создаем объект QRCode с параметрами. Параметр version отвечает за размер кода. Данный параметр варьируется от 1 до 40. Чем больше значение, тем больше размер создаваемого кода. Параметр error_correction отвечает за коррекцию ошибок. Ее желательно включить, так как при создании кода с картинкой часть кода будет нарушена, что затруднит считывание. Параметр box_size отвечает за количество создаваемых пиксельных квадратов. Чем больше данный параметр, тем больше квадратиков создается в коде. И наконец, параметр border указывает, какой толщины рамку делать у кода. 0 – без рамки, а дальше уже идет толщина. В данном коде выставлено в 1, чтобы рамка все же была, но была минимальной, так как без рамки смотрится все это дело не очень.
Добавляем текст в код:
Создаем его в черно-белом цвете. После чего сохраняем с заранее предопределенным именем файла. Важно, сохранять в png. После чего выводим сообщение о том, что код сохранен и запускаем функцию main(), чтобы у пользователя отобразилось начальное меню. После чего выходим из функции.
На следующем этапе создадим функцию qr_round(), которая будет создавать код с закругленными квадратами. В этой функции все, как и в предыдущей, за исключением того, что при создании QR-кода указываем параметры image_factory, который отвечает за указание при создании кода использовать модуль StyledPilImage, и module_drawer, который и отвечает за отрисовку скругленных квадратов.
Далее создаем функцию для создания кода с картинкой в центре. Здесь, помимо текста кода запрашиваем у пользователя путь к картинке. Выполняем проверку корректности пути, после чего создаем нужный код. В остальном код идентичен предыдущему, за исключением параметра embeded_image_path, в котором указывается путь к картинке, которая и помещается в центре.
Так же я создал отдельную функцию, которая и запрашивает у пользователя, какой код из стандартных от желает создать. И в зависимости от выбора запускает ту или иную функцию. На входе функция standard_code_param() ничего не принимает. Ее задача только лишь определить чего хочет пользователь.
А вот дальше начинается интересное. Нашел я данный код на просторах Хабра у пользователя с ником Pornosenok. Поэтому, никаких авторских прав на данный код не имею. Вот ссылка на статью с данным кодом. Так же в статье есть ссылка на GitHub, откуда и был взят модуль для создания кода с фоном из картинки. То есть здесь я только лишь вызываю необходимую функцию. Вся «магия» твориться в подключенном модуле. Данный модуль, как и код скрипта будет во вложении к статье, а также его можно скачать напрямую с GitHub, по ссылке в статье на Хабре. Спасибо доброму человеку!
Теперь нужно сделать функцию, которая будет считывать содержимое QR-кода, то есть тот текст, который там содержится и выводить на экран. Назову ее qr_read(). Здесь указывается путь к картинке с кодом, далее, данная картинка считывается с помощью cv2, после чего декодируется с помощью pyzbar и функции decode, чтобы вывести на экран информацию в utf-8. Так как считанные данные находятся в байтовом виде. Ну и печатаем полученный текст на экране. В случае, если код не будет прочитан и словарь вернется пустым, выводим на экран сообщение.
И еще одна функция определения пользовательского выбора. Подробно на ней останавливаться не стоит. Обычное сравнение с помощью if-elif-else.
И функция main(), в которой также запрашивается пользовательский ввод.
Вот и все. Скрипт для создания и чтения QR-кода можно считать завершенным. Осталось только протестировать его функции, как все создается и отображается.
Давайте создадим по коду из каждой функции. И посмотрим, что получилось:
Да простит, меня Codeby за взятое лого )), но вроде бы неплохо. Можно было бы и лучше, но я проверил каждый код. Все читается замечательно.
И напоследок попробовал прочитать созданное изображение с помощью скрипта. Получилось вот что:
Все так, как и было закодировано.
Спасибо за внимание. Надеюсь, что данная информация будет кому-нибудь полезной
Что понадобиться?
Понадобиться, несмотря на простоту кода довольно много библиотек. Библиотека qrcode, для создания кода, библиотека path для работы с путями. opencv-python для распознавания картинки с кодом. pyzbar для считывания кодов. И еще нужен будет небольшой модуль, который я нашел и который делает создание кода довольно забавным делом. Об этом будет подробнее ниже. А сейчас, устанавливаем библиотеки:
pip install opencv-python qrcode[pil] pyzbar path
После чего импортируем в модуль:
Python:
import os
import qrcode
import cv2
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers import RoundedModuleDrawer
from pyzbar.pyzbar import decode
from path import Path
Теперь приступим к созданию функций. Я разделил их по функционалу, чтобы не запрашивать слишком много данных у пользователя. Хотя, если по правильному, то следовало бы. Но, для демонстрационного кода, да и в большинстве случаев, размер и качество создаваемы QR достаточно для того, чтобы они считывались телефоном. Создадим функцию qr_standard(). Данная функция создает код с классическими квадратиками. Ничего необычного и нестандартного. Для начала запрашиваем текст, который нужно закодировать. Это может быть ссылка на ресурс или просто какое-либо приветствие.
qr_text = input('\n[+] Введите текст или ссылку: ')
Создаем объект QRCode с параметрами. Параметр version отвечает за размер кода. Данный параметр варьируется от 1 до 40. Чем больше значение, тем больше размер создаваемого кода. Параметр error_correction отвечает за коррекцию ошибок. Ее желательно включить, так как при создании кода с картинкой часть кода будет нарушена, что затруднит считывание. Параметр box_size отвечает за количество создаваемых пиксельных квадратов. Чем больше данный параметр, тем больше квадратиков создается в коде. И наконец, параметр border указывает, какой толщины рамку делать у кода. 0 – без рамки, а дальше уже идет толщина. В данном коде выставлено в 1, чтобы рамка все же была, но была минимальной, так как без рамки смотрится все это дело не очень.
Добавляем текст в код:
qr.add_data(qr_text)
Создаем его в черно-белом цвете. После чего сохраняем с заранее предопределенным именем файла. Важно, сохранять в png. После чего выводим сообщение о том, что код сохранен и запускаем функцию main(), чтобы у пользователя отобразилось начальное меню. После чего выходим из функции.
Python:
img = qr.make_image(fill_color="black", back_color="white")
img.save('qr_standard.png')
print('[+] QR-код создан и сохранен: "qr_standard1.png"')
main()
return
Python:
def qr_standard():
qr_text = input('\n[+] Введите текст или ссылку: ')
qr = qrcode.QRCode(
version=3,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=15,
border=1,
)
qr.add_data(qr_text)
img = qr.make_image(fill_color="black", back_color="white")
img.save('qr_standard.png')
print('[+] QR-код создан и сохранен: "qr_standard1.png"')
main()
return
На следующем этапе создадим функцию qr_round(), которая будет создавать код с закругленными квадратами. В этой функции все, как и в предыдущей, за исключением того, что при создании QR-кода указываем параметры image_factory, который отвечает за указание при создании кода использовать модуль StyledPilImage, и module_drawer, который и отвечает за отрисовку скругленных квадратов.
img = qr.make_image(image_factory=StyledPilImage, module_drawer=RoundedModuleDrawer())
Python:
def qr_round():
qr_text = input('\n[+] Введите текст или ссылку: ')
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H, version=3, border=1, box_size=15)
qr.add_data(qr_text)
img = qr.make_image(image_factory=StyledPilImage, module_drawer=RoundedModuleDrawer())
img.save('qr_round.png')
print('[+] QR-код создан и сохранен: "qr_round.png"')
main()
return
Далее создаем функцию для создания кода с картинкой в центре. Здесь, помимо текста кода запрашиваем у пользователя путь к картинке. Выполняем проверку корректности пути, после чего создаем нужный код. В остальном код идентичен предыдущему, за исключением параметра embeded_image_path, в котором указывается путь к картинке, которая и помещается в центре.
Python:
def qr_image():
qr_text = input('\n[+] Введите текст или ссылку: ')
qr_path = input('[+] Введите путь к картинке >>> ')
while not os.path.isfile(qr_path):
qr_path = input('\n[-] Неверный путь.\n[+] Введите путь к картинке >>> ')
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H, version=3, border=1, box_size=15)
qr.add_data(qr_text)
img = qr.make_image(image_factory=StyledPilImage, embeded_image_path=qr_path)
img.save('qr_image.png')
print('[+] QR-код создан и сохранен: "qr_image.png"')
main()
return
Так же я создал отдельную функцию, которая и запрашивает у пользователя, какой код из стандартных от желает создать. И в зависимости от выбора запускает ту или иную функцию. На входе функция standard_code_param() ничего не принимает. Ее задача только лишь определить чего хочет пользователь.
Python:
def standard_code_param():
qr_vid = input('[+] Выберите вид QR-кода:\n\t[1] Простой QR-код;\n\t[2] QR с закругленными элементами;'
'\n\t[3] QR с картинкой по центру\n\t[4] Выход\n\t>>> ')
if qr_vid == "1":
qr_standard()
elif qr_vid == "2":
qr_round()
elif qr_vid == '3':
qr_image()
elif qr_vid == "4":
exit(0)
else:
standard_code_param()
А вот дальше начинается интересное. Нашел я данный код на просторах Хабра у пользователя с ником Pornosenok. Поэтому, никаких авторских прав на данный код не имею. Вот ссылка на статью с данным кодом. Так же в статье есть ссылка на GitHub, откуда и был взят модуль для создания кода с фоном из картинки. То есть здесь я только лишь вызываю необходимую функцию. Вся «магия» твориться в подключенном модуле. Данный модуль, как и код скрипта будет во вложении к статье, а также его можно скачать напрямую с GitHub, по ссылке в статье на Хабре. Спасибо доброму человеку!
Python:
def back_image_qr():
text_code = input('\n[+] Введите тест или ссылку для создания qr-кода: ')
image_path = input('[+] Введите путь к картинке фона >>> ')
while not os.path.isfile(image_path):
image_path = input('\n[-] Неверный путь.\n[+] Введите путь к картинке фона >>> ')
path_to_download = Path().joinpath(image_path)
path_to_save = Path().joinpath('qr_back_image.png')
gen_qr_code(text_code, path_to_download, path_to_save)
print(f'[+] QR-код создан и сохранен: {path_to_save}')
main()
return
Теперь нужно сделать функцию, которая будет считывать содержимое QR-кода, то есть тот текст, который там содержится и выводить на экран. Назову ее qr_read(). Здесь указывается путь к картинке с кодом, далее, данная картинка считывается с помощью cv2, после чего декодируется с помощью pyzbar и функции decode, чтобы вывести на экран информацию в utf-8. Так как считанные данные находятся в байтовом виде. Ну и печатаем полученный текст на экране. В случае, если код не будет прочитан и словарь вернется пустым, выводим на экран сообщение.
Python:
def qr_read():
img_path = input('\n[+] Введите путь к QR-коду >>> ')
while not os.path.isfile(img_path):
img_path = input('\nНеверный путь.\n[+] Введите путь к QR-коду >>> ')
img = cv2.imread(img_path)
if not decode(img):
print('[-] Не могу прочитать данные')
else:
bartext = decode(img)[0][0].decode('utf-8')
print(f'Текст QR-кода: {bartext}')
main()
return
И еще одна функция определения пользовательского выбора. Подробно на ней останавливаться не стоит. Обычное сравнение с помощью if-elif-else.
Python:
def user_check(qr_style):
if qr_style == "1":
standard_code_param()
elif qr_style == '2':
back_image_qr()
elif qr_style == "3":
qr_read()
elif qr_style == "4":
exit(0)
else:
print('\n[-] Сделайте правильный выбор!')
main()
return
И функция main(), в которой также запрашивается пользовательский ввод.
Python:
def main():
qr_style = input('\n[+] Выберите действие:\n\t[1] Создать стандартный QR-код;\n'
'\t[2] Создать QR-код с фоном-картинкой;\n\t[3] Чтение содержимого QR-кода\n\t[4] Выход\n\t>>> ')
user_check(qr_style)
Вот и все. Скрипт для создания и чтения QR-кода можно считать завершенным. Осталось только протестировать его функции, как все создается и отображается.
Python:
# pip install opencv-python qrcode[pil] pyzbar path
import os
import qrcode
import cv2
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers import RoundedModuleDrawer
from pyzbar.pyzbar import decode
from path import Path
# код пользователя с хабр!
from main_qr import gen_qr_code
# создаем простой код
def qr_standard():
qr_text = input('\n[+] Введите текст или ссылку: ')
qr = qrcode.QRCode(
version=3,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=15,
border=1,
)
qr.add_data(qr_text)
img = qr.make_image(fill_color="black", back_color="white")
img.save('qr_standard.png')
print('[+] QR-код создан и сохранен: "qr_standard1.png"')
main()
return
# создаем код с закругленными элементами
def qr_round():
qr_text = input('\n[+] Введите текст или ссылку: ')
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H, version=3, border=1, box_size=15)
qr.add_data(qr_text)
img = qr.make_image(image_factory=StyledPilImage, module_drawer=RoundedModuleDrawer())
img.save('qr_round.png')
print('[+] QR-код создан и сохранен: "qr_round.png"')
main()
return
# создаем код с картинкой посередине
def qr_image():
qr_text = input('\n[+] Введите текст или ссылку: ')
qr_path = input('[+] Введите путь к картинке >>> ')
while not os.path.isfile(qr_path):
qr_path = input('\n[-] Неверный путь.\n[+] Введите путь к картинке >>> ')
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H, version=3, border=1, box_size=15)
qr.add_data(qr_text)
img = qr.make_image(image_factory=StyledPilImage, embeded_image_path=qr_path)
img.save('qr_image.png')
print('[+] QR-код создан и сохранен: "qr_image.png"')
main()
return
# выбор параметров стандартного кода
def standard_code_param():
qr_vid = input('[+] Выберите вид QR-кода:\n\t[1] Простой QR-код;\n\t[2] QR с закругленными элементами;'
'\n\t[3] QR с картинкой по центру\n\t[4] Выход\n\t>>> ')
if qr_vid == "1":
qr_standard()
elif qr_vid == "2":
qr_round()
elif qr_vid == '3':
qr_image()
elif qr_vid == "4":
exit(0)
else:
standard_code_param()
# создание кода с картинкой на фоне
def back_image_qr():
text_code = input('\n[+] Введите тест или ссылку для создания qr-кода: ')
image_path = input('[+] Введите путь к картинке фона >>> ')
while not os.path.isfile(image_path):
image_path = input('\n[-] Неверный путь.\n[+] Введите путь к картинке фона >>> ')
path_to_download = Path().joinpath(image_path)
path_to_save = Path().joinpath('qr_back_image.png')
gen_qr_code(text_code, path_to_download, path_to_save)
print(f'[+] QR-код создан и сохранен: {path_to_save}')
main()
return
# чтение содержимого кода
def qr_read():
img_path = input('\n[+] Введите путь к QR-коду >>> ')
while not os.path.isfile(img_path):
img_path = input('\nНеверный путь.\n[+] Введите путь к QR-коду >>> ')
img = cv2.imread(img_path)
if not decode(img):
print('[-] Не могу прочитать данные')
else:
bartext = decode(img)[0][0].decode('utf-8')
print(f'Текст QR-кода: {bartext}')
main()
return
# обработка пользовательского выбора
def user_check(qr_style):
if qr_style == "1":
standard_code_param()
elif qr_style == '2':
back_image_qr()
elif qr_style == "3":
qr_read()
elif qr_style == "4":
exit(0)
else:
print('\n[-] Сделайте правильный выбор!')
main()
return
# выбор типа кода, создание или чтение
def main():
qr_style = input('\n[+] Выберите действие:\n\t[1] Создать стандартный QR-код;\n'
'\t[2] Создать QR-код с фоном-картинкой;\n\t[3] Чтение содержимого QR-кода\n\t[4] Выход\n\t>>> ')
user_check(qr_style)
if __name__ == "__main__":
main()
Давайте создадим по коду из каждой функции. И посмотрим, что получилось:
Да простит, меня Codeby за взятое лого )), но вроде бы неплохо. Можно было бы и лучше, но я проверил каждый код. Все читается замечательно.
И напоследок попробовал прочитать созданное изображение с помощью скрипта. Получилось вот что:
Все так, как и было закодировано.
Спасибо за внимание. Надеюсь, что данная информация будет кому-нибудь полезной