Merge branch 'promag-2019-08-add-border-feature' from #126 which adds support to

boarder option during Qr encoding.
This commit is contained in:
Nikos Ftylitakis 2019-09-29 20:20:39 +03:00
commit 703667de30
5 changed files with 79 additions and 20 deletions

View File

@ -206,10 +206,12 @@ Image{
Or use the encoding function with the optional custom settings that are passed like URL query parameters: Or use the encoding function with the optional custom settings that are passed like URL query parameters:
| attribute name | value | description | <<<<<<< HEAD
| -------------- | ---------- | --------------------------------------------- | | attribute name | value | description |
| correctionLevel | L, M, Q, H | the error correction level | | --------------- | ---------- | --------------------------------------------- |
| format | qrcode | the encode formatter. Currently only QR Code. | | border | true, false | whether the image has a border |
| correctionLevel | L, M, Q, H | the error correction level |
| format | qrcode | the encode formatter. Currently only QR Code. |
the size of the image can be adjusted by using the Image.sourceWidth and Image.sourceHeight properties of Image QML element. the size of the image can be adjusted by using the Image.sourceWidth and Image.sourceHeight properties of Image QML element.

View File

@ -10,6 +10,7 @@ ApplicationWindow {
minimumWidth: formatGroupBox.width + minimumWidth: formatGroupBox.width +
errorCorrectionlevelGroupBox.width + errorCorrectionlevelGroupBox.width +
borderStatus.width +
5 * advancedOptions.spacing 5 * advancedOptions.spacing
property bool isAdvancedOptionsEnabled: advancedSwitch.position; property bool isAdvancedOptionsEnabled: advancedSwitch.position;
@ -75,6 +76,12 @@ ApplicationWindow {
model: ["L", "M", "Q", "H"] model: ["L", "M", "Q", "H"]
} }
} }
Switch {
id: borderStatus
text: "Border"
anchors.verticalCenter: parent.verticalCenter
}
} }
Rectangle { Rectangle {
@ -102,7 +109,8 @@ ApplicationWindow {
if(mainWindow.isAdvancedOptionsEnabled) { if(mainWindow.isAdvancedOptionsEnabled) {
return "image://QZXing/encode/" + inputField.text + return "image://QZXing/encode/" + inputField.text +
"?correctionLevel=" + errorCorrectionlevelCombo.currentText + "?correctionLevel=" + errorCorrectionlevelCombo.currentText +
"&format=" + formatCombo.currentText "&format=" + formatCombo.currentText +
"&border=" + borderStatus.position;
} }
else else
return "image://QZXing/encode/" + inputField.text; return "image://QZXing/encode/" + inputField.text;

View File

@ -575,34 +575,55 @@ QString QZXing::decodeSubImageQML(const QUrl &imageUrl,
QImage QZXing::encodeData(const QString& data, QImage QZXing::encodeData(const QString& data,
const EncoderFormat encoderFormat, const EncoderFormat encoderFormat,
const QSize encoderImageSize, const QSize encoderImageSize,
const EncodeErrorCorrectionLevel errorCorrectionLevel) const EncodeErrorCorrectionLevel errorCorrectionLevel,
const bool border)
{
return encodeData(data,
QZXingEncoderConfig(encoderFormat,
encoderImageSize,
errorCorrectionLevel,
border));
}
QImage QZXing::encodeData(const QString &data, const QZXingEncoderConfig &encoderConfig)
{ {
QImage image; QImage image;
try { try {
switch (encoderFormat) { switch (encoderConfig.format) {
case EncoderFormat_QR_CODE: case EncoderFormat_QR_CODE:
{ {
Ref<qrcode::QRCode> barcode = qrcode::Encoder::encode( Ref<qrcode::QRCode> barcode = qrcode::Encoder::encode(
data.toStdString(), data.toStdString(),
errorCorrectionLevel == EncodeErrorCorrectionLevel_H ? encoderConfig.errorCorrectionLevel == EncodeErrorCorrectionLevel_H ?
qrcode::ErrorCorrectionLevel::H : qrcode::ErrorCorrectionLevel::H :
(errorCorrectionLevel == EncodeErrorCorrectionLevel_Q ? (encoderConfig.errorCorrectionLevel == EncodeErrorCorrectionLevel_Q ?
qrcode::ErrorCorrectionLevel::Q : qrcode::ErrorCorrectionLevel::Q :
(errorCorrectionLevel == EncodeErrorCorrectionLevel_M ? (encoderConfig.errorCorrectionLevel == EncodeErrorCorrectionLevel_M ?
qrcode::ErrorCorrectionLevel::M : qrcode::ErrorCorrectionLevel::M :
qrcode::ErrorCorrectionLevel::L))); qrcode::ErrorCorrectionLevel::L)));
Ref<qrcode::ByteMatrix> bytesRef = barcode->getMatrix(); Ref<qrcode::ByteMatrix> bytesRef = barcode->getMatrix();
const std::vector< std::vector <zxing::byte> >& bytes = bytesRef->getArray(); const std::vector< std::vector <zxing::byte> >& bytes = bytesRef->getArray();
image = QImage(int(bytesRef->getWidth()), int(bytesRef->getHeight()), QImage::Format_ARGB32); const int width = int(bytesRef->getWidth()) + (encoderConfig.border ? 2 : 0);
for(size_t i=0; i<bytesRef->getWidth(); i++) const int height = int(bytesRef->getHeight()) + (encoderConfig.border ? 2 : 0);
for(size_t j=0; j<bytesRef->getHeight(); j++) const QRgb black = qRgb(0, 0, 0);
image.setPixel(int(i), int(j), bytes[j][i] ? const QRgb white = qRgb(255, 255, 255);
qRgb(0,0,0) :
qRgb(255,255,255));
image = image.scaled(encoderImageSize); image = QImage(width, height, QImage::Format_ARGB32);
image.fill(white);
int offset = encoderConfig.border ? 1 : 0;
for (size_t i=0; i<bytesRef->getWidth(); ++i) {
for (size_t j=0; j<bytesRef->getHeight(); ++j) {
if (bytes[j][i]) {
image.setPixel(offset+int(i), offset+int(j), black);
}
}
}
image = image.scaled(encoderConfig.imageSize);
break; break;
} }
case EncoderFormat_INVALID: case EncoderFormat_INVALID:

View File

@ -36,6 +36,7 @@ class MultiFormatReader;
class ResultMetadata; class ResultMetadata;
} }
class ImageHandler; class ImageHandler;
struct QZXingEncoderConfig;
/** /**
* A class containing a very very small subset of the ZXing library. * A class containing a very very small subset of the ZXing library.
@ -179,10 +180,17 @@ public slots:
/** /**
* The main encoding function. Currently supports only Qr code encoding * The main encoding function. Currently supports only Qr code encoding
*/ */
static QImage encodeData(const QString &data,
const QZXingEncoderConfig &encoderConfig);
/**
* Overloaded function of encodeData.
*/
static QImage encodeData(const QString& data, static QImage encodeData(const QString& data,
const EncoderFormat encoderFormat = EncoderFormat_QR_CODE, const EncoderFormat encoderFormat = EncoderFormat_QR_CODE,
const QSize encoderImageSize = QSize(240, 240), const QSize encoderImageSize = QSize(240, 240),
const EncodeErrorCorrectionLevel errorCorrectionLevel = EncodeErrorCorrectionLevel_L); const EncodeErrorCorrectionLevel errorCorrectionLevel = EncodeErrorCorrectionLevel_L,
const bool border = false);
/** /**
* Get the prossecing time in millisecond of the last decode operation. * Get the prossecing time in millisecond of the last decode operation.
@ -230,5 +238,20 @@ private:
bool isThreaded; bool isThreaded;
}; };
typedef struct QZXingEncoderConfig
{
QZXing::EncoderFormat format;
QSize imageSize;
QZXing::EncodeErrorCorrectionLevel errorCorrectionLevel;
bool border;
QZXingEncoderConfig(const QZXing::EncoderFormat encoderFormat_ = QZXing::EncoderFormat_QR_CODE,
const QSize encoderImageSize_ = QSize(240, 240),
const QZXing::EncodeErrorCorrectionLevel errorCorrectionLevel_ = QZXing::EncodeErrorCorrectionLevel_L,
const bool border_ = false) :
format(encoderFormat_), imageSize(encoderImageSize_),
errorCorrectionLevel(errorCorrectionLevel_), border(border_) {}
} QZXingEncoderConfig;
#endif // QZXING_H #endif // QZXING_H

View File

@ -28,8 +28,9 @@ QImage QZXingImageProvider::requestImage(const QString &id, QSize *size, const Q
QString data; QString data;
QZXing::EncoderFormat format = QZXing::EncoderFormat_QR_CODE; QZXing::EncoderFormat format = QZXing::EncoderFormat_QR_CODE;
QZXing::EncodeErrorCorrectionLevel correctionLevel = QZXing::EncodeErrorCorrectionLevel_L; QZXing::EncodeErrorCorrectionLevel correctionLevel = QZXing::EncodeErrorCorrectionLevel_L;
bool border = false;
int customSettingsIndex = id.lastIndexOf(QRegularExpression("\\?(correctionLevel|format)=")); int customSettingsIndex = id.lastIndexOf(QRegularExpression("\\?(correctionLevel|format|border)="));
if(customSettingsIndex >= 0) if(customSettingsIndex >= 0)
{ {
int startOfDataIndex = slashIndex + 1; int startOfDataIndex = slashIndex + 1;
@ -56,12 +57,16 @@ QImage QZXingImageProvider::requestImage(const QString &id, QSize *size, const Q
correctionLevel = QZXing::EncodeErrorCorrectionLevel_M; correctionLevel = QZXing::EncodeErrorCorrectionLevel_M;
else if(correctionLevelString == "L") else if(correctionLevelString == "L")
correctionLevel = QZXing::EncodeErrorCorrectionLevel_L; correctionLevel = QZXing::EncodeErrorCorrectionLevel_L;
if (optionQuery.hasQueryItem("border")) {
border = QVariant(optionQuery.queryItemValue("border")).toBool();
}
} else } else
{ {
data = id.mid(slashIndex + 1); data = id.mid(slashIndex + 1);
} }
QImage result = QZXing::encodeData(data, format, requestedSize, correctionLevel); QImage result = QZXing::encodeData(data, format, requestedSize, correctionLevel, border);
*size = result.size(); *size = result.size();
return result; return result;
} }