文字表示付きQRコードの作成

# 目的
csvファイルに書き込んだ文字情報とURLを使って文字表示付きのQRコードを作成します。

下記サイトを参考にさせていただきました。
[Pythonによる文字表示付きQRコードの大量生成](https://qiita.com/Kosuke_Matsui/items/abc379e4486eeacd283e)

# 開発環境
Python version:3.9.7
OS: windows 10.0

# イメージ
![スクリーンショット 2022-05-30 9.15.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/b5d84f68-ffb9-c598-44cb-7a8f51aa5336.png)
表示したい文字と生成したいQRコードのアドレスをcsvファイルとして準備します。
PySimpleGUIを使って、csvファイルを選択し、処理をして、my_qr_codeのフォルダにQRコードを保存できるようにします。

# プログラム
プログラムは、[git](https://github.com/yutti/study/tree/main/QR_code)に置いています。
大体は、[こちら](https://qiita.com/Kosuke_Matsui/items/abc379e4486eeacd283e)の記事を参考にしていただければ、理解できると思います。ただ、私的に使いやすくするため、上記の記事から２点変更しました。

### 1.QRコードのサイズに合わせた文字情報の位置調整
いろいろなURLアドレスでQRコードを生成させると、QRコードのサイズが異なってしまい、QRコード下部に表示させた文字が重なることがありました。そのため、QRコードのサイズが異なった場合は、位置を調整できるようにしています。プログラムでは、if文で記載している部分になります。

### 2.文字情報の日本語化
日本語を入力すると、文字化けをしてしまいました。日本語化は、fontを日本語に対応したもの変更する必要があります。
windowsでは、　```font_path = 'C:\Windows\Fonts\meiryo.ttc' ```にすると、文字化けは解消します。

```test.py
import os
import csv
import pandas as pd
import qrcode
import PySimpleGUI as sg
from PIL import Image, ImageDraw, ImageFont

def add_margin(pil_img, top, right, bottom, left, color):
    width, height = pil_img.size
    new_width = width + right + left
    new_height = height + top + bottom
    result = Image.new(pil_img.mode, (new_width, new_height), color)
    result.paste(pil_img, (left, top))
    return result

def qr_generator(number,name,url):
    qr = qrcode.QRCode(
        version=2,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=9,
        border=4,
    )

    qr.add_data(url)
    qr.make(fit=True)

    img = qr.make_image(fill_color="black", back_color="white").convert('L')

#   get the QR code image height to adjust the name position
    im_height = img.height
    if im_height <= 300:
        but_margin , draw_h = 50,  250
    elif im_height > 300 and im_height <= 350:
        but_margin , draw_h = 83,  283
    elif im_height > 350 and im_height <= 400:
        but_margin , draw_h = 117,  317
    else:
        but_margin , draw_h = 150, 350

    img_add = add_margin(img, -15, -15, but_margin, -15, '#ffffff')   
    draw = ImageDraw.Draw(img_add)

    font_path = 'C:\Windows\Fonts\meiryo.ttc' # Windows font path to use Japanese  
    font = ImageFont.truetype(font_path, 20)
    num = number

    draw.text((15, draw_h), name, font=font, fill='#000000')      
    img_add.save('./my_qr_code/' + number + '.png', quality=95)

def select_csv():
    sg.change_look_and_feel('Light Blue 2')
    layout = [[sg.Text('Data'),
               sg.InputText('(file path)', key='filepath'),
               sg.FilesBrowse('Select a file', target='filepath',
                              file_types=(('csv file', '.csv'),))],
              [sg.Submit(), sg.Cancel()]
              
              ]
    window = sg.Window('Charting', layout)
    while True:
        event, values = window.read()
        if event in ('Cancel', sg.WIN_CLOSED):
            return None
        if event == 'Submit':
            break
    window.close()
    filepath = values.get('filepath')
    if filepath == '(file path)':
        filepath = None

    return filepath

def main():
    # make the folder to put QR code if don't exist.
    new_path = "my_qr_code"
    if not os.path.exists(new_path):
        os.mkdir(new_path)

    # get urls and name for csv
    csv_path = select_csv()
    if csv_path is None:
        return

    df = pd.read_csv(csv_path)
    df_name = df['name']
    df_url = df['url']    

    # make QR code
    for number in range(int(len(df))):
        qr_generator(str(1000+number),df_name[number],df_url[number])  

if __name__ == '__main__':
    main()
```