diff --git a/harbour-barcode.pro b/harbour-barcode.pro
index d64a5af..53ff8e5 100644
--- a/harbour-barcode.pro
+++ b/harbour-barcode.pro
@@ -115,6 +115,7 @@ HARBOUR_QML_COMPONENTS = \
$${HARBOUR_LIB_QML}/HarbourHighlightIcon.qml \
$${HARBOUR_LIB_QML}/HarbourHintIconButton.qml \
$${HARBOUR_LIB_QML}/HarbourHorizontalSwipeHint.qml \
+ $${HARBOUR_LIB_QML}/HarbourInvertEffect.qml \
$${HARBOUR_LIB_QML}/HarbourPressEffect.qml
OTHER_FILES += $${HARBOUR_QML_COMPONENTS}
diff --git a/harbour-lib b/harbour-lib
index 323fc6b..070dc9e 160000
--- a/harbour-lib
+++ b/harbour-lib
@@ -1 +1 @@
-Subproject commit 323fc6b6c98f85265e55425c22d617991178cc44
+Subproject commit 070dc9ede17b99ca748ac414a0256f2d96be2a77
diff --git a/qml/components/GalleryImage.qml b/qml/components/GalleryImage.qml
index 185e447..24920c5 100644
--- a/qml/components/GalleryImage.qml
+++ b/qml/components/GalleryImage.qml
@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
-Copyright (c) 2020-2021 Slava Monich
+Copyright (c) 2020-2022 Slava Monich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -25,6 +25,8 @@ THE SOFTWARE.
import QtQuick 2.0
import Sailfish.Silica 1.0
+import "../harbour"
+
SilicaFlickable {
id: galleryImage
@@ -33,6 +35,7 @@ SilicaFlickable {
property real orientation
property bool isLandscape
property alias source: image.source
+ property bool invert
readonly property real minZoomX: (implicitWidth > width) ? width/implicitWidth : 0.1
readonly property real minZoomY: (implicitHeight > height) ? height/implicitHeight : 0.1
@@ -105,6 +108,11 @@ SilicaFlickable {
readonly property real xSize: d * Math.max(Math.abs(Math.cos(r - a)), Math.abs(Math.cos(r + a)))
readonly property real ySize: d * Math.max(Math.abs(Math.sin(r - a)), Math.abs(Math.sin(r + a)))
+ layer.enabled: invert
+ layer.effect: HarbourInvertEffect {
+ source: image
+ }
+
anchors.centerIn: parent
scale: actualZoom
smooth: true
diff --git a/qml/components/ViewFinder.qml b/qml/components/ViewFinder.qml
index bbafc87..cdf6114 100644
--- a/qml/components/ViewFinder.qml
+++ b/qml/components/ViewFinder.qml
@@ -2,21 +2,21 @@ import QtQuick 2.0
import QtMultimedia 5.4
import Sailfish.Silica 1.0
+import "../harbour"
+
VideoOutput {
id: viewFinder
- layer.enabled: true
anchors.fill: parent
fillMode: VideoOutput.Stretch
property alias beepSource: beep.source
property size viewfinderResolution
- property bool completed
property bool showFocusArea: true
property real digitalZoom: 1.0
+ property bool invert
readonly property bool cameraActive: camera.cameraState === Camera.ActiveState
- readonly property bool tapFocusActive: focusTimer.running
readonly property bool flashOn: camera.flash.mode !== Camera.FlashOff
// Not sure why not just camera.orientation but this makes the camera
// behave similar to what it does for Jolla Camera
@@ -26,6 +26,15 @@ VideoOutput {
// Camera.ActiveStatus and doesn't emit maximumDigitalZoomChanged signal
signal maximumDigitalZoom(var value)
+ // Internal properties
+ readonly property bool _tapFocusActive: focusTimer.running
+ property bool _completed
+
+ layer.enabled: invert
+ layer.effect: HarbourInvertEffect {
+ source: viewFinder
+ }
+
onOrientationChanged: {
if (camera.cameraState !== Camera.UnloadedState) {
reloadTimer.restart()
@@ -52,7 +61,7 @@ VideoOutput {
if (viewfinderResolution) {
camera.viewfinder.resolution = viewfinderResolution
}
- completed = true
+ _completed = true
}
function turnFlashOn() {
@@ -131,15 +140,15 @@ VideoOutput {
imageProcessing.whiteBalanceMode: flashOn ?
CameraImageProcessing.WhiteBalanceFlash :
CameraImageProcessing.WhiteBalanceTungsten
- cameraState: (completed && !reloadTimer.running) ?
+ cameraState: (_completed && !reloadTimer.running) ?
Camera.ActiveState : Camera.UnloadedState
exposure {
exposureCompensation: 1.0
exposureMode: Camera.ExposureAuto
}
focus {
- focusMode: tapFocusActive ? Camera.FocusAuto : Camera.FocusContinuous
- focusPointMode: tapFocusActive ? Camera.FocusPointCustom : Camera.FocusPointAuto
+ focusMode: _tapFocusActive ? Camera.FocusAuto : Camera.FocusContinuous
+ focusPointMode: _tapFocusActive ? Camera.FocusPointCustom : Camera.FocusPointAuto
}
onCameraStatusChanged: {
if (cameraStatus === Camera.ActiveStatus) {
diff --git a/qml/pages/ScanPage.qml b/qml/pages/ScanPage.qml
index 6e166a1..b7edad9 100644
--- a/qml/pages/ScanPage.qml
+++ b/qml/pages/ScanPage.qml
@@ -34,27 +34,30 @@ import "../components"
import "../harbour"
Page {
- id: scanPage
+ id: thisPage
allowedOrientations: window.allowedOrientations
+ property bool autoScan
+ readonly property bool cameraActive: viewFinder && viewFinder.cameraActive
+
+ // Internal properties
property Item galleryImage
property Item viewFinder
property Item hint
- property bool showMarker
- property bool autoScan
- property int scanTimeout: 60
+ property bool showMarker
+ readonly property bool mustShowViewFinder: (thisPage.status === PageStatus.Active) && Qt.application.active && !scanningGalleryImage && !showMarker
readonly property bool hintActive: hint && hint.visible
- readonly property bool cameraActive: viewFinder && viewFinder.cameraActive
readonly property bool landscapeLayout: width > height
- readonly property bool mustShowViewFinder: (scanPage.status === PageStatus.Active) && Qt.application.active && !scanningGalleryImage && !showMarker
readonly property bool scanningGalleryImage: galleryImage && galleryImage.visible
- readonly property bool useVolumeKeys: AppSettings.volumeZoom && (scanPage.status === PageStatus.Active) && Qt.application.active
+ readonly property bool useVolumeKeys: AppSettings.volumeZoom && (thisPage.status === PageStatus.Active) && Qt.application.active
+ readonly property int toolIconFadeDuration: 64
+ readonly property int scanTimeout: 60
- readonly property var volumeUp: Qt.createQmlObject(BarcodeUtils.mediaKeyQml, scanPage, "VolumeKey")
- readonly property var volumeDown: Qt.createQmlObject(BarcodeUtils.mediaKeyQml, scanPage, "VolumeKey")
- readonly property var permissions: Qt.createQmlObject(BarcodeUtils.permissionsQml, scanPage, "Permissions")
+ readonly property var volumeUp: Qt.createQmlObject(BarcodeUtils.mediaKeyQml, thisPage, "VolumeKey")
+ readonly property var volumeDown: Qt.createQmlObject(BarcodeUtils.mediaKeyQml, thisPage, "VolumeKey")
+ readonly property var permissions: Qt.createQmlObject(BarcodeUtils.permissionsQml, thisPage, "Permissions")
Binding { target: permissions; property: "enabled"; value: useVolumeKeys }
Binding { target: volumeUp; property: "enabled"; value: useVolumeKeys }
@@ -173,7 +176,7 @@ Page {
function showHint(text) {
if (!hint) {
- hint = hintComponent.createObject(scanPage)
+ hint = hintComponent.createObject(thisPage)
}
hint.text = text
hint.opacity = 1.0
@@ -215,7 +218,7 @@ Page {
}
onStatusChanged: {
- if (scanPage.status === PageStatus.Inactive) {
+ if (thisPage.status === PageStatus.Inactive) {
console.log("Page is INACTIVE")
// stop scanning if page is not active
destroyScanner()
@@ -267,6 +270,7 @@ Page {
markerColor: AppSettings.markerColor
rotation: orientationAngle()
canGrab: (!galleryImage || !galleryImage.moving) && !galleryScanTimer.running
+ inverted: invertButton.down
decodingHints: AppSettings.decodingHints
onDecodingFinished: {
@@ -274,7 +278,7 @@ Page {
statusText.text = ""
applyResult(image, result)
if (AppSettings.resultViewDuration > 0) {
- scanPage.showMarker = true
+ thisPage.showMarker = true
resultViewTimer.restart()
}
if (buzzLoader.item) {
@@ -318,7 +322,7 @@ Page {
id: resultViewTimer
interval: AppSettings.resultViewDuration * 1000
- onTriggered: scanPage.showMarker = false
+ onTriggered: thisPage.showMarker = false
}
Component {
@@ -336,7 +340,7 @@ Page {
GalleryImage {
visible: false
- isLandscape: scanPage.isLandscape
+ isLandscape: thisPage.isLandscape
z: 1
}
}
@@ -345,6 +349,7 @@ Page {
id: scanPageFlickable
anchors.fill: parent
+ interactive: !(invertButton.visible && invertButton.down)
PullDownMenu {
enabled: scanner.idle && !hintActive
@@ -366,7 +371,7 @@ Page {
//: Page header
//% "Select image"
title: qsTrId("gallery-title"),
- allowedOrientations: scanPage.allowedOrientations
+ allowedOrientations: thisPage.allowedOrientations
})
var imageUrl, imageOrientation
picker.imageSelected.connect(function(url, orientation) {
@@ -493,8 +498,8 @@ Page {
readonly property int landscapeHeight: Math.floor((parent.width/parent.height > ratio) ? parent.height : (parent.width / ratio))
anchors.centerIn: parent
- width: scanningGalleryImage ? parent.width : (scanPage.isPortrait ? portraitWidth : landscapeWidth)
- height: scanningGalleryImage ? parent.height : (scanPage.isPortrait ? portraitHeight : landscapeHeight)
+ width: scanningGalleryImage ? parent.width : (thisPage.isPortrait ? portraitWidth : landscapeWidth)
+ height: scanningGalleryImage ? parent.height : (thisPage.isPortrait ? portraitHeight : landscapeHeight)
color: "#20000000"
opacity: markerImage.visible ? 0 : 1
Behavior on opacity { FadeAnimation { } }
@@ -520,7 +525,7 @@ Page {
anchors.centerIn: viewFinderContainer
z: 2
- source: scanPage.showMarker ? markerImageProvider.source : ""
+ source: thisPage.showMarker ? markerImageProvider.source : ""
visible: status === Image.Ready
cache: false
}
@@ -547,7 +552,7 @@ Page {
}
opacity: (TorchSupported && !scanningGalleryImage) ? 1.0 : 0.0
visible: TorchSupported && opacity > 0.0
- Behavior on opacity { FadeAnimation { } }
+ Behavior on opacity { FadeAnimation { duration: toolIconFadeDuration } }
icon.source: viewFinder && viewFinder.flashOn ?
Qt.resolvedUrl("img/flash-on.svg") :
Qt.resolvedUrl("img/flash-off.svg")
@@ -555,8 +560,8 @@ Page {
//: Hint label
//% "Toggle flashlight"
hint: qsTrId("hint-toggle-flash")
- onShowHint: scanPage.showHint(hint)
- onHideHint: scanPage.hideHint()
+ onShowHint: thisPage.showHint(hint)
+ onHideHint: thisPage.hideHint()
}
Slider {
@@ -632,6 +637,7 @@ Page {
readonly property url icon_16_9: Qt.resolvedUrl("img/resolution_16_9.svg")
readonly property url icon_4_3: Qt.resolvedUrl("img/resolution_4_3.svg")
+ readonly property bool isNeeded: viewFinderContainer.canSwitchResolutions && scanner.scanState !== BarcodeScanner.Scanning
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
@@ -641,9 +647,9 @@ Page {
sourceSize: Qt.size(Theme.iconSizeMedium, Theme.iconSizeMedium)
rotation: isLandscape ? 90 : 0
}
- opacity: (scanningGalleryImage || !viewFinderContainer.canSwitchResolutions)? 0.0 : 1.0
+ opacity: isNeeded ? 1.0 : 0.0
visible: opacity > 0.0
- Behavior on opacity { FadeAnimation { } }
+ Behavior on opacity { FadeAnimation { duration: toolIconFadeDuration } }
onClicked: AppSettings.wideMode = !AppSettings.wideMode
hint: isLandscape ?
//: Hint label
@@ -652,8 +658,27 @@ Page {
//: Hint label
//% "Switch the aspect ratio between 9:16 and 3:4"
qsTrId("hint-aspect-ratio")
- onShowHint: scanPage.showHint(hint)
- onHideHint: scanPage.hideHint()
+ onShowHint: thisPage.showHint(hint)
+ onHideHint: thisPage.hideHint()
+ }
+
+ HarbourHintIconButton {
+ id: invertButton
+
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ icon {
+ source: Qt.resolvedUrl("img/invert.svg")
+ sourceSize: Qt.size(Theme.iconSizeMedium, Theme.iconSizeMedium)
+ rotation: invertButton.down ? 180 : 0
+ }
+ opacity: ((viewFinder || galleryImage) && !ratioButton.isNeeded) ? 1.0 : 0.0
+ visible: opacity > 0.0
+ Behavior on opacity { FadeAnimation { duration: toolIconFadeDuration } }
+ Binding { target: viewFinder; property: "invert"; value: invertButton.down }
+ Binding { target: galleryImage; property: "invert"; value: invertButton.down }
}
}
@@ -725,7 +750,7 @@ Page {
} else {
var component = Qt.createComponent("../components/VCard.qml")
if (component.status === Component.Ready) {
- vcard = component.createObject(scanPage, { content: vcardText })
+ vcard = component.createObject(thisPage, { content: vcardText })
}
}
} else {
@@ -783,11 +808,11 @@ Page {
//: Hint label
//% "Show EU digital COVID certificate"
hint: qsTrId("hint-covid_certificate")
- onShowHint: scanPage.showHint(hint)
- onHideHint: scanPage.hideHint()
+ onShowHint: thisPage.showHint(hint)
+ onHideHint: thisPage.hideHint()
onClicked: {
pageStack.push("CovidPage.qml", {
- allowedOrientations: scanPage.allowedOrientations,
+ allowedOrientations: thisPage.allowedOrientations,
text: dgCert.text
})
}
@@ -802,11 +827,11 @@ Page {
//: Hint label
//% "Open contact card"
hint: qsTrId("hint-open_contact_card")
- onShowHint: scanPage.showHint(hint)
- onHideHint: scanPage.hideHint()
+ onShowHint: thisPage.showHint(hint)
+ onHideHint: thisPage.hideHint()
onClicked: {
pageStack.push("VCardPage.qml", {
- allowedOrientations: scanPage.allowedOrientations,
+ allowedOrientations: thisPage.allowedOrientations,
contact: clickableResult.vcard.contact(),
}).saveContact.connect(function() {
pageStack.pop()
@@ -832,8 +857,8 @@ Page {
//: Hint label
//% "Add event to calendar"
hint: qsTrId("hint-add_to_calendar")
- onShowHint: scanPage.showHint(hint)
- onHideHint: scanPage.hideHint()
+ onShowHint: thisPage.showHint(hint)
+ onHideHint: thisPage.hideHint()
}
HarbourHintIconButton {
@@ -855,8 +880,8 @@ Page {
//: Hint label
//% "Open URL in default application"
qsTrId("hint-open_url")
- onShowHint: scanPage.showHint(hint)
- onHideHint: scanPage.hideHint()
+ onShowHint: thisPage.showHint(hint)
+ onHideHint: thisPage.hideHint()
onClicked: {
console.log("opening", clickableResult.text)
Qt.openUrlExternally(clickableResult.text)
@@ -875,8 +900,8 @@ Page {
//: Hint label
//% "Copy to clipboard"
hint: qsTrId("hint-copy-clipboard")
- onShowHint: scanPage.showHint(hint)
- onHideHint: scanPage.hideHint()
+ onShowHint: thisPage.showHint(hint)
+ onHideHint: thisPage.hideHint()
}
Timer {
@@ -902,7 +927,7 @@ Page {
remorse.execute(resultItem, qsTrId("history-menu-delete_remorse"),
function() {
HistoryModel.remove(0)
- if (scanPage.status === PageStatus.Active) {
+ if (thisPage.status === PageStatus.Active) {
HistoryModel.commitChanges()
}
remorse.destroy()
@@ -933,7 +958,7 @@ Page {
onClicked: {
pageStack.push("TextPage.qml", {
- allowedOrientations: scanPage.allowedOrientations,
+ allowedOrientations: thisPage.allowedOrientations,
hasImage: AppSettings.saveImages,
recordId: clickableResult.recordId,
text: clickableResult.text,
diff --git a/qml/pages/img/invert.svg b/qml/pages/img/invert.svg
new file mode 100644
index 0000000..052f09d
--- /dev/null
+++ b/qml/pages/img/invert.svg
@@ -0,0 +1,27 @@
+
+
diff --git a/src/scanner/BarcodeScanner.cpp b/src/scanner/BarcodeScanner.cpp
index 11d1100..731ff9e 100644
--- a/src/scanner/BarcodeScanner.cpp
+++ b/src/scanner/BarcodeScanner.cpp
@@ -37,12 +37,23 @@ THE SOFTWARE.
#include
#include
-#if HARBOUR_DEBUG
+#define HARBOUR_BARCODE_DEBUG_IMAGES
+#ifdef HARBOUR_BARCODE_DEBUG_IMAGES
+// In debug build saving debug images is enabled by default, in release
+// if HARBOUR_BARCODE_DEBUG_IMAGES environment is set 1 (or anything
+// non-zero, actually)
+# if HARBOUR_DEBUG
+# define HARBOUR_BARCODE_DEBUG_IMAGES_ENABLED true
+# else
+# define HARBOUR_BARCODE_DEBUG_IMAGES_ENABLED \
+ (qgetenv("HARBOUR_BARCODE_DEBUG_IMAGES").toInt() > 0)
+# endif // HARBOUR_DEBUG
#include
static const QDir debugImageDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/codereader");
+static const bool debugImageEnabled = HARBOUR_BARCODE_DEBUG_IMAGES_ENABLED;
static void saveDebugImage(const QImage& aImage, const QString& aFileName)
{
- if (!aImage.isNull()) {
+ if (debugImageEnabled && debugImageDir.exists() && !aImage.isNull()) {
QString path = debugImageDir.filePath(aFileName);
if (aImage.save(path)) {
HDEBUG("image saved:" << qPrintable(path));
@@ -57,7 +68,9 @@ static void saveDebugImage(const QImage& aImage, const QString& aFileName)
// BarcodeScanner::Private
// ==========================================================================
-class BarcodeScanner::Private : public QObject {
+class BarcodeScanner::Private :
+ public QObject
+{
Q_OBJECT
public:
Private(BarcodeScanner* aParent);
@@ -65,11 +78,11 @@ class BarcodeScanner::Private : public QObject {
BarcodeScanner* scanner();
- bool setViewFinderRect(const QRect& aRect);
- bool setViewFinderItem(QObject* aValue);
- bool setMarkerColor(QString aValue);
- bool setRotation(int aDegrees);
- void startScanning(int aTimeout);
+ bool setViewFinderRect(const QRect&);
+ bool setViewFinderItem(QObject*);
+ bool setMarkerColor(QString);
+ bool setRotation(int);
+ void startScanning(int);
void stopScanning();
void grabImage();
void decodingThread();
@@ -77,15 +90,16 @@ class BarcodeScanner::Private : public QObject {
Q_SIGNALS:
void needImage();
- void decodingDone(QImage image, Decoder::Result result);
+ void decodingDone(QImage, Decoder::Result);
public Q_SLOTS:
void onScanningTimeout();
- void onDecodingDone(QImage aImage, Decoder::Result aResult);
+ void onDecodingDone(QImage, Decoder::Result);
void onGrabImage();
public:
bool iCanGrab;
+ bool iInverted;
bool iGrabbing;
bool iScanning;
bool iNeedImage;
@@ -95,6 +109,7 @@ public Q_SLOTS:
ScanState iLastKnownState;
QImage iCaptureImage;
+ bool iCaptureImageInverted;
QQuickItem* iViewFinderItem;
QTimer* iScanTimeout;
@@ -110,6 +125,7 @@ public Q_SLOTS:
BarcodeScanner::Private::Private(BarcodeScanner* aParent) :
QObject(aParent),
iCanGrab(true),
+ iInverted(false),
iGrabbing(false),
iScanning(false),
iNeedImage(false),
@@ -117,6 +133,7 @@ BarcodeScanner::Private::Private(BarcodeScanner* aParent) :
iTimedOut(false),
iRotation(0),
iLastKnownState(Idle),
+ iCaptureImageInverted(false),
iViewFinderItem(NULL),
iScanTimeout(new QTimer(this)),
iMarkerColor(QColor(0, 255, 0)), // default green
@@ -142,12 +159,16 @@ BarcodeScanner::Private::~Private()
iDecodingFuture.waitForFinished();
}
-inline BarcodeScanner* BarcodeScanner::Private::scanner()
+inline
+BarcodeScanner*
+BarcodeScanner::Private::scanner()
{
return qobject_cast(parent());
}
-bool BarcodeScanner::Private::setViewFinderRect(const QRect& aRect)
+bool
+BarcodeScanner::Private::setViewFinderRect(
+ const QRect& aRect)
{
if (iViewFinderRect != aRect) {
// iViewFinderRect is accessed by decodingThread() thread
@@ -159,7 +180,9 @@ bool BarcodeScanner::Private::setViewFinderRect(const QRect& aRect)
return false;
}
-bool BarcodeScanner::Private::setViewFinderItem(QObject* aItem)
+bool
+BarcodeScanner::Private::setViewFinderItem(
+ QObject* aItem)
{
QQuickItem* item = qobject_cast(aItem);
if (iViewFinderItem != item) {
@@ -169,7 +192,9 @@ bool BarcodeScanner::Private::setViewFinderItem(QObject* aItem)
return false;
}
-bool BarcodeScanner::Private::setMarkerColor(QString aValue)
+bool
+BarcodeScanner::Private::setMarkerColor(
+ QString aValue)
{
if (QColor::isValidColor(aValue)) {
QColor color(aValue);
@@ -181,7 +206,9 @@ bool BarcodeScanner::Private::setMarkerColor(QString aValue)
return false;
}
-bool BarcodeScanner::Private::setRotation(int aDegrees)
+bool
+BarcodeScanner::Private::setRotation(
+ int aDegrees)
{
if (iRotation != aDegrees) {
iDecodingMutex.lock();
@@ -192,7 +219,9 @@ bool BarcodeScanner::Private::setRotation(int aDegrees)
return false;
}
-void BarcodeScanner::Private::startScanning(int aTimeout)
+void
+BarcodeScanner::Private::startScanning(
+ int aTimeout)
{
if (!iScanning) {
iScanning = true;
@@ -210,7 +239,8 @@ void BarcodeScanner::Private::startScanning(int aTimeout)
}
}
-void BarcodeScanner::Private::stopScanning()
+void
+BarcodeScanner::Private::stopScanning()
{
// stopping a running scanning process
iDecodingMutex.lock();
@@ -223,7 +253,8 @@ void BarcodeScanner::Private::stopScanning()
updateScanState();
}
-void BarcodeScanner::Private::grabImage()
+void
+BarcodeScanner::Private::grabImage()
{
QQuickWindow* window = iViewFinderItem->window();
if (window) {
@@ -239,13 +270,15 @@ void BarcodeScanner::Private::grabImage()
HDEBUG(image);
iDecodingMutex.lock();
iCaptureImage = image;
+ iCaptureImageInverted = iInverted;
iDecodingEvent.wakeAll();
iDecodingMutex.unlock();
}
}
}
-void BarcodeScanner::Private::onGrabImage()
+void
+BarcodeScanner::Private::onGrabImage()
{
if (iViewFinderItem && iScanning) {
if (iCanGrab) {
@@ -257,7 +290,8 @@ void BarcodeScanner::Private::onGrabImage()
}
}
-void BarcodeScanner::Private::decodingThread()
+void
+BarcodeScanner::Private::decodingThread()
{
HDEBUG("decodingThread() is called from " << QThread::currentThread());
@@ -266,6 +300,7 @@ void BarcodeScanner::Private::decodingThread()
QImage image;
qreal scale = 1;
bool rotated = false;
+ bool inverted = false;
int scaledWidth = 0;
const int maxSize = 800;
@@ -282,8 +317,10 @@ void BarcodeScanner::Private::decodingThread()
}
if (iAbortScan) {
image = QImage();
+ inverted = false;
} else {
image = iCaptureImage;
+ inverted = iCaptureImageInverted;
iCaptureImage = QImage();
}
viewFinderRect = iViewFinderRect;
@@ -341,7 +378,7 @@ void BarcodeScanner::Private::decodingThread()
HDEBUG("extracted" << image);
saveDebugImage(image, "debug_cropped.bmp");
-#if HARBOUR_DEBUG
+#ifdef HARBOUR_BARCODE_DEBUG_IMAGES
// In debug build, ~/Pictures/codereader/debug_input.bmp gets
// processed instead of the actual captured and cropped image,
// if such file exists. Normally it doesn't exist. If you need
@@ -350,7 +387,7 @@ void BarcodeScanner::Private::decodingThread()
//
// $ mkdir ~/Pictures/codereader
//
- // try debuging the image, abort/finish the decoding the then
+ // try debuging the image, abort/finish the decoding, then
//
// $ cd ~/Pictures/codereader
// $ cp debug_cropped.bmp debug_input.bmp
@@ -358,7 +395,7 @@ void BarcodeScanner::Private::decodingThread()
// And then whenever you start capture this file will be picked
// up instead of the actual input.
//
- if (debugImageDir.exists()) {
+ if (debugImageEnabled && debugImageDir.exists()) {
QImage debugImage;
QString filePath = debugImageDir.filePath("debug_input.bmp");
if (debugImage.load(filePath)) {
@@ -366,7 +403,7 @@ void BarcodeScanner::Private::decodingThread()
image = debugImage;
}
}
-#endif // HARBOUR_DEBUG
+#endif // HARBOUR_BARCODE_DEBUG_IMAGES
QImage scaledImage;
if (image.width() > maxSize && image.height() > maxSize) {
@@ -426,6 +463,9 @@ void BarcodeScanner::Private::decodingThread()
if (result.isValid()) {
HDEBUG("decoding succeeded:" << result.getText() << result.getPoints());
+ if (inverted) {
+ image.invertPixels();
+ }
if (scale > 1 || rotated) {
// The image could be a) scaled and b) rotated. Convert
// points to the original coordinate system
@@ -613,11 +653,29 @@ void BarcodeScanner::setCanGrab(bool aCanGrab)
}
}
-bool BarcodeScanner::grabbing() const
+bool
+BarcodeScanner::grabbing() const
{
return iPrivate->iGrabbing;
}
+bool
+BarcodeScanner::inverted() const
+{
+ return iPrivate->iInverted;
+}
+
+void
+BarcodeScanner::setInverted(
+ bool aInverted)
+{
+ if (iPrivate->iInverted != aInverted) {
+ HDEBUG(aInverted);
+ iPrivate->iInverted = aInverted;
+ Q_EMIT invertedChanged();
+ }
+}
+
uint BarcodeScanner::decodingHints() const
{
return iPrivate->iDecodingHints;
diff --git a/src/scanner/BarcodeScanner.h b/src/scanner/BarcodeScanner.h
index a5b9096..e61c3db 100644
--- a/src/scanner/BarcodeScanner.h
+++ b/src/scanner/BarcodeScanner.h
@@ -32,7 +32,8 @@ THE SOFTWARE.
#include
#include
-class BarcodeScanner : public QObject {
+class BarcodeScanner : public QObject
+{
Q_OBJECT
Q_PROPERTY(QObject* viewFinderItem READ viewFinderItem WRITE setViewFinderItem NOTIFY viewFinderItemChanged)
Q_PROPERTY(QRect viewFinderRect READ viewFinderRect WRITE setViewFinderRect NOTIFY viewFinderRectChanged)
@@ -41,6 +42,7 @@ class BarcodeScanner : public QObject {
Q_PROPERTY(ScanState scanState READ scanState NOTIFY scanStateChanged)
Q_PROPERTY(bool canGrab READ canGrab WRITE setCanGrab NOTIFY canGrabChanged)
Q_PROPERTY(bool grabbing READ grabbing NOTIFY grabbingChanged)
+ Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged)
Q_PROPERTY(uint decodingHints READ decodingHints WRITE setDecodingHints NOTIFY decodingHintsChanged)
Q_ENUMS(ScanState)
@@ -57,30 +59,33 @@ class BarcodeScanner : public QObject {
BarcodeScanner(QObject* aParent = Q_NULLPTR);
virtual ~BarcodeScanner();
- Q_INVOKABLE void startScanning(int aTimeout);
+ Q_INVOKABLE void startScanning(int);
Q_INVOKABLE void stopScanning();
QObject* viewFinderItem() const;
- void setViewFinderItem(QObject* aItem);
+ void setViewFinderItem(QObject*);
const QRect& viewFinderRect() const;
- void setViewFinderRect(const QRect& aRect);
+ void setViewFinderRect(const QRect&);
QString markerColor() const;
- void setMarkerColor(QString aValue);
+ void setMarkerColor(QString);
int rotation() const;
- void setRotation(int aDegrees);
+ void setRotation(int);
ScanState scanState() const;
bool canGrab() const;
- void setCanGrab(bool aValue);
+ void setCanGrab(bool);
bool grabbing() const;
+ bool inverted() const;
+ void setInverted(bool);
+
uint decodingHints() const;
- void setDecodingHints(uint aValue);
+ void setDecodingHints(uint);
Q_SIGNALS:
void decodingFinished(QImage image, QVariantMap result);
@@ -91,6 +96,7 @@ class BarcodeScanner : public QObject {
void scanStateChanged();
void canGrabChanged();
void grabbingChanged();
+ void invertedChanged();
void decodingHintsChanged();
private: