Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- #
- # Electron Cash - lightweight Bitcoin client
- # Copyright (C) 2019 Axel Gembe <derago@gmail.com>
- #
- # Permission is hereby granted, free of charge, to any person
- # obtaining a copy of this software and associated documentation files
- # (the "Software"), to deal in the Software without restriction,
- # including without limitation the rights to use, copy, modify, merge,
- # publish, distribute, sublicense, and/or sell copies of the Software,
- # and to permit persons to whom the Software is furnished to do so,
- # subject to the following conditions:
- #
- # The above copyright notice and this permission notice shall be
- # included in all copies or substantial portions of the Software.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- # SOFTWARE.
- import sys
- import ctypes
- from enum import IntEnum
- from PyQt5.QtMultimedia import QCameraInfo, QCamera, QCameraImageCapture, QVideoFrame, QAbstractVideoBuffer
- from PyQt5.QtMultimediaWidgets import QCameraViewfinder
- from PyQt5.QtWidgets import QDialog, QVBoxLayout
- from PyQt5.QtGui import QImage
- from electroncash.i18n import _
- from electroncash.util import print_error
- if sys.platform == 'darwin':
- name = 'libzbar.dylib'
- elif sys.platform in ('windows', 'win32'):
- name = 'libzbar-0.dll'
- else:
- name = 'libzbar.so.0'
- try:
- libzbar = ctypes.cdll.LoadLibrary(name)
- libzbar.zbar_image_create.restype = ctypes.c_void_p
- libzbar.zbar_image_set_data.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
- libzbar.zbar_image_scanner_create.restype = ctypes.c_void_p
- libzbar.zbar_image_scanner_get_results.restype = ctypes.c_void_p
- libzbar.zbar_symbol_set_first_symbol.restype = ctypes.c_void_p
- libzbar.zbar_symbol_get_data.restype = ctypes.c_void_p
- except:
- print_error("Failed to load zbar: {}".format(repr(sys.exc_info()[1])))
- libzbar = None
- FOURCC_Y800 = 0x30303859
- class ZbarSymbolType(IntEnum):
- EAN2 = 2,
- EAN5 = 5,
- EAN8 = 8,
- UPCE = 9,
- ISBN10 = 10,
- UPCA = 12,
- EAN13 = 13,
- ISBN13 = 14,
- COMPOSITE = 15,
- I25 = 25,
- DATABAR = 34,
- DATABAR_EXP = 35,
- CODABAR = 38,
- CODE39 = 39,
- PDF417 = 57,
- QRCODE = 64,
- SQCODE = 80,
- CODE93 = 93,
- CODE128 = 128
- class ZbarConfig(IntEnum):
- ENABLE = 0
- class QrCameraDialog(QDialog):
- def __init__(self, parent):
- if libzbar is None:
- raise RuntimeError("Cannot start QR scanner; zbar not available.")
- QDialog.__init__(self, parent=parent)
- self.image_capture = None
- self.setWindowTitle(_("Scan QR Code"))
- vbox = QVBoxLayout()
- self.setLayout(vbox)
- self.viewfinder = QCameraViewfinder()
- vbox.addWidget(self.viewfinder)
- # Set up zbar
- libzbar.zbar_set_verbosity(100)
- self.zbar_image = libzbar.zbar_image_create()
- self.zbar_scanner = libzbar.zbar_image_scanner_create()
- # Disable all symbols
- for sym_type in ZbarSymbolType:
- libzbar.zbar_image_scanner_set_config(self.zbar_scanner, int(sym_type), int(ZbarConfig.ENABLE), 0)
- # Enable only QR codes
- libzbar.zbar_image_scanner_set_config(self.zbar_scanner, int(ZbarSymbolType.QRCODE), int(ZbarConfig.ENABLE), 1)
- def closeEvent(self, e):
- libzbar.zbar_image_scanner_destroy(self.zbar_scanner)
- libzbar.zbar_image_ref(self.zbar_image, -1)
- def scan(self, device=''):
- device_info = None
- for camera in QCameraInfo.availableCameras():
- if camera.deviceName() == device:
- device_info = camera
- break
- if not device_info:
- device_info = QCameraInfo.defaultCamera()
- if not device_info or device_info.isNull():
- # TODO: Error message
- return ''
- camera = QCamera(device_info)
- camera.setViewfinder(self.viewfinder)
- camera.setCaptureMode(QCamera.CaptureStillImage)
- self.image_capture = QCameraImageCapture(camera)
- self.image_capture.setCaptureDestination(QCameraImageCapture.CaptureToBuffer)
- self.image_capture.imageAvailable.connect(self.handle_frame)
- camera.start()
- self.image_capture.capture()
- self.exec()
- camera.stop()
- return ''
- def handle_frame(self, frame_id, frame):
- image_format = QVideoFrame.imageFormatFromPixelFormat(frame.pixelFormat())
- if not frame.map(QAbstractVideoBuffer.ReadOnly):
- # FIXME: Handle
- return
- try:
- if image_format == QImage.Format_Invalid:
- # This frame was a format that can not be converter to an image pixel format
- img = QImage.fromData(frame.bits(), frame.mappedBytes())
- else:
- img = QImage(frame.bits(), frame.width(), frame.height(), image_format).copy()
- img = img.copy()
- finally:
- frame.unmap()
- # Convert to Y800 / GREY FourCC (single 8-bit channel)
- img = img.convertToFormat(QImage.Format_Grayscale8)
- self.handle_image(frame_id, img)
- self.image_capture.capture()
- def handle_image(self, frame_id, image: QImage):
- self.current_image = image
- libzbar.zbar_image_set_sequence(self.zbar_image, frame_id)
- libzbar.zbar_image_set_size(self.zbar_image, image.width(), image.height())
- libzbar.zbar_image_set_format(self.zbar_image, FOURCC_Y800)
- libzbar.zbar_image_set_data(self.zbar_image, image.bits().__int__(), image.byteCount())
- libzbar.zbar_image_scanner_recycle_image(self.zbar_scanner, self.zbar_image)
- libzbar.zbar_scan_image(self.zbar_scanner, self.zbar_image)
- result_set = libzbar.zbar_image_scanner_get_results(self.zbar_scanner)
- libzbar.zbar_image_set_symbols(self.zbar_image, result_set)
- #symbol = libzbar.zbar_symbol_set_first_symbol(result_set)
- detected_symbols = libzbar.zbar_symbol_set_get_size(result_set)
- print_error('detected {} symbol(s) in frame {}'.format(detected_symbols, frame_id))
- #print_error('captured {}'.format(frame_id))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement