[2−1]作成したQRコードを読み取り識別する

この記事は["QRコードを使った入場システムを自作する"](https://qiita.com/inchoXD/items/10e22dbde4a5d4724c44)シリーズの記事です。

#前回
["[1]独自のフォーマットに基づいてQRコードを発行する"](https://qiita.com/inchoXD/items/a8164c54ba8ae5bae74f)では独自のフォーマットのQRコードを発行してデータベースに登録することができました。
今回はデータベースに登録したQRコードの読み取り方です。

#QRコードを読み取るには
スキャナーを用意する予算がなかったのiOSアプリのPythonista3を利用してQRコードを読み取ります。
##手順
Pythonista3を利用しなくてもなんでも読み取った後の処理は同じです。

- QRコードをスキャン
- 読み取ったコードを文字列に変換
- MySQLで検索をかける

##Pythonista３でQRコードを読み取る方法
今回一番きつかったのがこの部分で、objective-cをPython上で動かさなければいけませんでした。
Pythonistaには標準で***objc_util***というモジュールが入っているのでそれを利用します。
###とは言っても...
objective-cなんか生まれてから一度も利用したことがなくswiftが主流？になってきているので今回は[こちら](https://forum.omz-software.com/topic/2779/barcode-qr-code-camera-scanner-demo-objc_util)を流用させていただいた。(一部改変)
###ということで
以下がソースコードになる。

```QRscanner1.py
# Barcode scanner demo for Pythonista

from objc_util import *
from ctypes import c_void_p
import mysql.connector as testdb
import ui
import sound


found_codes = set()
main_view = None

AVCaptureSession = ObjCClass('AVCaptureSession')
AVCaptureDevice = ObjCClass('AVCaptureDevice')
AVCaptureDeviceInput = ObjCClass('AVCaptureDeviceInput')
AVCaptureMetadataOutput = ObjCClass('AVCaptureMetadataOutput')
AVCaptureVideoPreviewLayer = ObjCClass('AVCaptureVideoPreviewLayer')
dispatch_get_current_queue = c.dispatch_get_current_queue
dispatch_get_current_queue.restype = c_void_p

#QRコードの読み取り
def captureOutput_didOutputMetadataObjects_fromConnection_(_self, _cmd, _output, _metadata_objects, _conn):
	objects = ObjCInstance(_metadata_objects)
	for obj in objects:
		s = str(obj.stringValue())
		if s not in found_codes:
			found_codes.add(s)
    #読み取り終了後にWindowを閉じる。
	main_view.close()

MetadataDelegate = create_objc_class('MetadataDelegate', methods=[captureOutput_didOutputMetadataObjects_fromConnection_], protocols=['AVCaptureMetadataOutputObjectsDelegate'])

@on_main_thread
def main():
	global main_view
	delegate = MetadataDelegate.new()
	main_view = ui.View(frame=(0, 0, 400, 400))
	main_view.name = 'Barcode Scanner'
	session = AVCaptureSession.alloc().init()
	device = AVCaptureDevice.defaultDeviceWithMediaType_('vide')
	_input = AVCaptureDeviceInput.deviceInputWithDevice_error_(device, None)
	if _input:
		session.addInput_(_input)
	else:
		print('Failed to create input')
		return
	output = AVCaptureMetadataOutput.alloc().init()
	queue = ObjCInstance(dispatch_get_current_queue())
	output.setMetadataObjectsDelegate_queue_(delegate, queue)
	session.addOutput_(output)
	output.setMetadataObjectTypes_(output.availableMetadataObjectTypes())
	prev_layer = AVCaptureVideoPreviewLayer.layerWithSession_(session)
	prev_layer.frame = ObjCInstance(main_view).bounds()
	prev_layer.setVideoGravity_('AVLayerVideoGravityResizeAspectFill')
	ObjCInstance(main_view).layer().addSublayer_(prev_layer)
	session.startRunning()
	main_view.present('sheet')
	main_view.wait_modal()
	session.stopRunning()
	delegate.release()
	session.release()
	output.release()
    #QRコードを読み取った際の処理
	if found_codes:
		#cur = conn.cursor()
		
		scan_code = str(''.join(found_codes))

		#table: QRidのデータを照合
		table = 'QRid'
		cur.execute("select * from QRid where QR=%s",(scan_code,))

		result = cur.fetchall()
		
		if len(result) == 0:
			sound.play_effect('digital:PhaserUp4')
			print('該当するデータがありません。')
			vibrate([50,0,50,0,50,0,50])
			
		else:
			sound.play_effect('arcade:Coin_5')
			print('ID'+'{:>15}'.format('DATE')+'{:>11}'.format('TIME'))
			for i in result:
				print(*i)
		

if __name__ == '__main__':
	#MySQLへ接続
	conn = testdb.connect(
    	user = 'test', 
    	password = '12345', 
    	host = '192.168.x.x',
    	port = '3306',
    	database='QRtest'
    )

	#接続ステータスを確認
	conn.ping(reconnect=True)
	print('[Status] ', end='')
	print(conn.is_connected())
	
	cur = conn.cursor()
	
	main()
	
	#MySQLへの接続を終了
	cur.close()
	conn.commit()
	conn.close()
```

スクリプトを走らせるとカメラウィンドウが表示されます。
<img width="320" alt="IMG_4029.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509951/f210f398-9587-5cce-a7ec-62b3752f98fb.png">
正常に読み取られるとこのウィンドウが閉じてコンソールが開きます。
<img width="320" alt="IMG_4028.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509951/06ec1d96-c573-d644-fa09-8ed07d1696bb.png">
MySQL上に登録されている情報が表示されれば成功です。
![スクリーンショット 2019-12-30 15.05.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509951/38c1dbcf-999d-b4f9-d47e-f115b0dc9c72.png)

#次回予告
[2-2]作成したQRコードを読み取り識別する。でよりわかりやすいGUIを追加します。読み取り機は次回で完成です。
<img width="320" alt="IMG_3969.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509951/7527bbc9-6bef-0736-238e-afe5d86f9efa.png">